用keras搭好模型架构之后的下一步,就是执行编译操作。在编译时,经常需要指定三个参数
loss
optimizer
metrics
这三个参数有两类选择:
使用字符串
使用标识符,如keras.losses,keras.optimizers,metrics包下面的函数
例如:
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
因为有时可以使用字符串,有时可以使用标识符,令人很想知道背后是如何操作的。下面分别针对optimizer,loss,metrics三种对象的获取进行研究。
optimizer
一个模型只能有一个optimizer,在执行编译的时候只能指定一个optimizer。
在keras.optimizers.py中,有一个get函数,用于根据用户传进来的optimizer参数获取优化器的实例:
def get(identifier): # 如果后端是tensorflow并且使用的是tensorflow自带的优化器实例,可以直接使用tensorflow原生的优化器 if K.backend() == 'tensorflow': # Wrap TF optimizer instances if isinstance(identifier, tf.train.Optimizer): return TFOptimizer(identifier) # 如果以json串的形式定义optimizer并进行参数配置 if isinstance(identifier, dict): return deserialize(identifier) elif isinstance(identifier, six.string_types): # 如果以字符串形式指定optimizer,那么使用优化器的默认配置参数 config = {'class_name': str(identifier), 'config': {}} return deserialize(config) if isinstance(identifier, Optimizer): # 如果使用keras封装的Optimizer的实例 return identifier else: raise ValueError('Could not interpret optimizer identifier: ' + str(identifier))
其中,deserilize(config)函数的作用就是把optimizer反序列化制造一个实例。
loss
keras.losses函数也有一个get(identifier)方法。其中需要注意以下一点:
如果identifier是可调用的一个函数名,也就是一个自定义的损失函数,这个损失函数返回值是一个张量。这样就轻而易举的实现了自定义损失函数。除了使用str和dict类型的identifier,我们也可以直接使用keras.losses包下面的损失函数。
def get(identifier): if identifier is None: return None if isinstance(identifier, six.string_types): identifier = str(identifier) return deserialize(identifier) if isinstance(identifier, dict): return deserialize(identifier) elif callable(identifier): return identifier else: raise ValueError('Could not interpret ' 'loss function identifier:', identifier)
metrics
在model.compile()函数中,optimizer和loss都是单数形式,只有metrics是复数形式。因为一个模型只能指明一个optimizer和loss,却可以指明多个metrics。metrics也是三者中处理逻辑最为复杂的一个。
在keras最核心的地方keras.engine.train.py中有如下处理metrics的函数。这个函数其实就做了两件事:
根据输入的metric找到具体的metric对应的函数
计算metric张量
在寻找metric对应函数时,有两种步骤:
使用字符串形式指明准确率和交叉熵
使用keras.metrics.py中的函数
def handle_metrics(metrics, weights=None): metric_name_prefix = 'weighted_' if weights is not None else '' for metric in metrics: # 如果metrics是最常见的那种:accuracy,交叉熵 if metric in ('accuracy', 'acc', 'crossentropy', 'ce'): # custom handling of accuracy/crossentropy # (because of class mode duality) output_shape = K.int_shape(self.outputs[i]) # 如果输出维度是1或者损失函数是二分类损失函数,那么说明是个二分类问题,应该使用二分类的accuracy和二分类的的交叉熵 if (output_shape[-1] == 1 or self.loss_functions[i] == losses.binary_crossentropy): # case: binary accuracy/crossentropy if metric in ('accuracy', 'acc'): metric_fn = metrics_module.binary_accuracy elif metric in ('crossentropy', 'ce'): metric_fn = metrics_module.binary_crossentropy # 如果损失函数是sparse_categorical_crossentropy,那么目标y_input就不是one-hot的,所以就需要使用sparse的多类准去率和sparse的多类交叉熵 elif self.loss_functions[i] == losses.sparse_categorical_crossentropy: # case: categorical accuracy/crossentropy # with sparse targets if metric in ('accuracy', 'acc'): metric_fn = metrics_module.sparse_categorical_accuracy elif metric in ('crossentropy', 'ce'): metric_fn = metrics_module.sparse_categorical_crossentropy else: # case: categorical accuracy/crossentropy if metric in ('accuracy', 'acc'): metric_fn = metrics_module.categorical_accuracy elif metric in ('crossentropy', 'ce'): metric_fn = metrics_module.categorical_crossentropy if metric in ('accuracy', 'acc'): suffix = 'acc' elif metric in ('crossentropy', 'ce'): suffix = 'ce' weighted_metric_fn = weighted_masked_objective(metric_fn) metric_name = metric_name_prefix + suffix else: # 如果输入的metric不是字符串,那么就调用metrics模块获取 metric_fn = metrics_module.get(metric) weighted_metric_fn = weighted_masked_objective(metric_fn) # Get metric name as string if hasattr(metric_fn, 'name'): metric_name = metric_fn.name else: metric_name = metric_fn.__name__ metric_name = metric_name_prefix + metric_name with K.name_scope(metric_name): metric_result = weighted_metric_fn(y_true, y_pred, weights=weights, mask=masks[i]) # Append to self.metrics_names, self.metric_tensors, # self.stateful_metric_names if len(self.output_names) > 1: metric_name = self.output_names[i] + '_' + metric_name # Dedupe name j = 1 base_metric_name = metric_name while metric_name in self.metrics_names: metric_name = base_metric_name + '_' + str(j) j += 1 self.metrics_names.append(metric_name) self.metrics_tensors.append(metric_result) # Keep track of state updates created by # stateful metrics (i.e. metrics layers). if isinstance(metric_fn, Layer) and metric_fn.stateful: self.stateful_metric_names.append(metric_name) self.stateful_metric_functions.append(metric_fn) self.metrics_updates += metric_fn.updates
无论怎么使用metric,最终都会变成metrics包下面的函数。当使用字符串形式指明accuracy和crossentropy时,keras会非常智能地确定应该使用metrics包下面的哪个函数。因为metrics包下的那些metric函数有不同的使用场景,例如:
有的处理的是one-hot形式的y_input(数据的类别),有的处理的是非one-hot形式的y_input
有的处理的是二分类问题的metric,有的处理的是多分类问题的metric
当使用字符串“accuracy”和“crossentropy”指明metric时,keras会根据损失函数、输出层的shape来确定具体应该使用哪个metric函数。在任何情况下,直接使用metrics下面的函数名是总不会出错的。
keras.metrics.py文件中也有一个get(identifier)函数用于获取metric函数。
def get(identifier): if isinstance(identifier, dict): config = {'class_name': str(identifier), 'config': {}} return deserialize(config) elif isinstance(identifier, six.string_types): return deserialize(str(identifier)) elif callable(identifier): return identifier else: raise ValueError('Could not interpret ' 'metric function identifier:', identifier)
如果identifier是字符串或者字典,那么会根据identifier反序列化出一个metric函数。
如果identifier本身就是一个函数名,那么就直接返回这个函数名。这种方式就为自定义metric提供了巨大便利。
keras中的设计哲学堪称完美。
以上这篇keras中的loss、optimizer、metrics用法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]