看了醒脑之书,突然被暴击到好清醒,也是低迷了好几个月了,有点儿失去方向,坚持一个月每天更新,找回之前向上的状态,毕竟,努力的女孩儿才最可爱。
先来鸡汤——
生活过的索然无味,那是因为过它的人正灰头土脸;
生活过得风生水起,那是因为过它的人时时处处事事都充满了仪式感。
Eat TensorFlow 2.0 in 30 days (1-1)
今天开始看30天吃掉那只TensorFlow2.0
TensorFlow的一般流程是这样的:
- 准备数据
- 定义模型
- 训练模型
- 评估模型
- 使用模型
- 保存模型
根据任务的不同,数据一般分为结构化数据、图片数据、文本数据、时间序列数据。
今天学了使用结构化数据,使用三层网络做二分类预测问题。按照基本步骤总结一下:
准备数据
1) 用Pandas导入数据:pd.read_csv()
2) 查看数据:head()
3) 用matplotlib查看数据分布:可用条形图(bar),直方图(hist),频率密度图(density)分析相关性
4) 预处理:
- 离散型变量用
get_dummies
转换为onehot编码,有缺失的用dummy_na=True
增添一列Nan - 数值型变量查看缺失值,用
fillna
填充,用isna
增添一列
定义模型
使用Keras接口有以下3种方式构建模型:使用Sequential按层顺序构建模型,使用函数式API构建任意结构模型,继承Model基类构建自定义模型。
tf.keras.backend.clear_session()
model = models.Sequential()
model.add(layers.Dense(20, activation= 'relu', input_shape=(15,)))
model.add(layers.Dense(10, activation= 'relu'))
model.add(layers.Dense(1, activation= 'sigmoid'))
model.summary()
训练模型
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['AUC'])
history = model.fit(x_train, y_train, batch_size=64, epochs=30, validation_split=0.2)
评估模型
画Loss和AUC图:
History 类对象包含两个属性,为epoch和history,history字典类型,包含val_loss、val_acc、 loss和acc四个值,History.history属性会把之前的值都保存在里面。画图的时候直接取出来就行:
train_metrics = history.history[metric]
val_metrics = history.history['val_' + metric]
epochs = range(1, len(train_metrics) + 1)
plt.plot(epochs, train_metrics, 'bo--')
plt.plot(epochs, val_metrics, 'ro--')
单纯评估模型用model.evaluate
:
model.evaluate(x = x_test, y = y_test)
使用模型
使用模型做预测用model.predict
:
model.predict(x_test[0:10])
# predict_classes可以自动四舍五入变成类别
model.predict_classes(x_test[0:10])
保存模型
训练好的模型可以使用Keras方式保存模型,也可以使用TensorFlow原生方式保存。前者仅仅适合使用Python环境恢复模型,后者则可以跨平台进行模型部署。
HDF5文件包含:模型的结构、权重、训练配置(损失函数、优化器等)、优化器的状态
用Keras方式保存模型结构和参数:
model.save('../mymodel/keras_model.h5')
用Tf方式保存模型结构和参数:
model.save('../mymodel/tf_model_savedmodel', save_format="tf")
用Keras保存模型权重:
model.save_weights('../mymodel/keras_model_weight.h5')
用Tf方式保存模型权重:
model.save_weights('../mymodel/tf_model_weights.ckpt',save_format = "tf")
用Keras恢复模型:
model = models.load_model('../mymodel/keras_model.h5')
model.load_weights('../mymodel/keras_model_weight.h5')
用Tf方式恢复模型:
model_loaded = tf.keras.models.load_model('../mymodel/tf_model_savedmodel')
消息队列——缓存策略
内存的随机读写速度是硬盘的10万倍,使用内存作为缓存来加速应用程序的访问速度,是几乎所有高性能系统都会采用的方法。
读写缓存:PageCache,OS利用系统空间的物理内存给文件做读写缓存,应用程序在写文件的时候,OS先把数据写到PageCache里,然后OS再异步地把数据更新到磁盘的文件中。消息队列采用这种方式,两点原因:1)读写比例1:1,只读缓存性能提升有限;2)Kafka依赖不同节点的多副本解决数据可靠性问题。
只读缓存:大部分读写不均衡的业务类应用,,使用只读缓存加速系统。
缓存更新策略:1)在更新数据的同时更新缓存;2)定期更新全部缓存;3)给缓存中每个数据设置一个有效期,让它自然过期以达到更新的目的。
缓存置换策略:1)命中率最高的策略,是根据业务逻辑,定制化的策略;2)通用的置换算法,最近最少使用算法(LRU),根据数据的历史访问记录来淘汰数据,把最长时间未被访问的数据置换出去。
LRU的实现
LRU
原理:最近使用一次,就移到头部
方法:使用一个链表保存缓存数据
1)新数据插入链表头
2)当缓存命中时,将数据移到链表头
3)当链表满时,将链表尾部数据丢弃
评价:
存在热点数据时,LRU效率很好,但偶发性的批量操作导致命中率下降,导致缓存污染。
LRU-K
原理:将最近使用1次的标准扩展为最近使用过k次。
方法:多维护一个队列,记录所有缓存数据被访问历史。只有当数据访问次数达到k次时才将数据放入缓存。需要淘汰时,淘汰第K次访问时间距离当前时间最大的数据。
1)新数据加入访问历史列表;
2)没有达到k次访问,按照FIFO淘汰;达到K次时,将数据索引从队列中删除,移到缓存队列中缓存,重新按照时间排序;
3)缓存数据队列被再次访问后,重新排序;
4)需要淘汰时,淘汰缓存队列中排在末尾的数据。
评价:
LRU-2是最优选择,命中率高,但内存消耗大。
Two Queues(2Q)
原理:将访问历史队列改为一个FIFO缓存队列。
方法:两个缓存队列(FIFO队列和LRU队列)当数据第一次被访问时,将数据缓存在FIFO队列中,再次被访问时,从FIFO队列移到LRU队列中。
1)新数据插入FIFO队列;
2)数据在FIFO中没被访问,按照FIFO规则淘汰;数据被访问,移到LRU队头;
3)数据在LRU被访问,移到队头;
4)LRU淘汰队尾数据。
评价:
命中率与LRU-2类似,内存消耗也类似。
Multi Queue(MQ)
原理:根据访问频率将数据划分多个LRU队列,优先缓存访问次数多的数据。
方法:划分多个LRU队列,每个队列对应不同的优先访问级。
1)新数据插入Q0;每个队列按照LRU管理数据;
2)数据访问次数达到一定时,提升优先级,加入高一级队列头;
3)数据在指定时间里没有被访问,降低优先级,从当前队列删除,加入低一级对头;
4)淘汰时,从最低一级开始按照LRU淘汰,将将数据从缓存删除,将索引加入Q-history头部;
5)Q-history数据被重新访问则重新计算优先级;
6)Q-history按照LRU淘汰数据的索引。
评价:
命中率高,但需要维护多个队列且定期扫描。