TensorFlow
TensorFlow官方文档参考:https://www.tensorflow.org/api_docs/python/
TensorFlow.Keras
keras是一个神经网络库,用来构建分类训练模型,keras必须与后端(如tensorflow,CNTK,Theano)结合才能运行, 其中后端可以随意切换
tf.keras与keras不同,前者是实现在TensorFlow下的,与TF结合更为紧密。其中keras代码可通过导入方式转为tf.keras代码,反之则不行,因为tf.keras还有keras不具有的tf相关特性,可理解为tf.keras为keras在tf上的一个扩充
也即tf.keras是不能切换后端的,keras灵活在后端切换上
keras官方文档
构建顺序模型
分类模型搭建,完整代码
# tf.keras.models.Sequential()
# 定义一个顺序模型
model = keras.models.Sequential()
'''
# 将输入矩阵[28,28]经过第一层后展平为[28*28,1]
model.add(keras.layers.Flatten(input_shape=[28,28]))
# 全连接层Dense,输出为300个节点
# relu: y = max(0, x)
model.add(keras.layers.Dense(300,activation='relu'))
model.add(keras.layers.Dense(100,activation='relu'))
# 最后输出10个分类,softmax会将向量变为概率
model.add(keras.layers.Dense(10,activation='softmax'))
'''
# 另一种构建模型的方式,传入一个列表,列表中为各层
model = keras.models.Sequential([
# 第一层要明确一下输入数据的shape,即input_shape=x_train.shape[1:]
keras.layers.Flatten(input_shape=[28, 28]),
keras.layers.Dense(300,activation='relu'),
keras.layers.Dense(100,activation='relu'),
keras.layers.Dense(10,activation='softmax')
])
# 损失函数loss:用sparse是因为每个y_train是一个值,而不是一个向量,需要将其转换为[10,1]的向量
# sparse以后就相当于对其进行了one-hot编码
# 若y_train本来就是向量的话,损失函数用categorical_crossentropy
model.compile(loss='sparse_categorical_crossentropy',
# 目标函数的优化算法,类似还有梯度下降、sgd等等
optimizer = 'adam',
# 评价指标metrics 其和损失函数类似,只不过其结果并不会作用于训练过程,只是输出作为参考。其中accuracy为模型的精确度
metrics = ["accuracy"])
# 查看模型信息
model.layers #查看层次
model.summary() #查看详细信息
# 开始训练 返回值为训练过程中的历史数据, 可用于画图分析训练效果
history = model.fit(x_train, y_train, epochs=10, validation_data=(x_valid, y_valid))
# 在测试集上验证效果
model.evaluate(x_test, y_test)
回归模型搭建:
model = keras.models.Sequential([
# 第一层要明确一下输入数据的shape,即input_shape=x_train.shape[1:]
keras.layers.Dense(30, activation='relu', input_shape=x_train.shape[1:]), # input_shape=8
keras.layers.Dense(1)
])
# 打印一下模型的信息
model.summary()
# 均方差 随机梯度下降
model.compile(loss='mean_squared_error', optimizer='sgd')
回调函数
回调函数是在模型的训练过程中进行调用实现的,作为一个参数传入model.fit()中,不同的函数有不同的功能
TensorBoard:可视化训练过程,可视化测试和训练的标准评估的动态图像,也可以可视化模型中不同层的激活值直方图
通过tensorboard --logdir=callbacks命令来启动tensorboard,其中callbacks为数据存放目录
EarlyStopping:当被监测的数据指标不再提升,则停止训练
monitor: 被监测的数据,默认为val_loss。
min_delta: 在被监测的数据中被认为是提升的最小变化, 例如,小于 min_delta 的绝对变化会被认为没有提升。
patience: 没有进步的训练轮数,在这之后训练就会被停止。
ModelCheckpoint:在每此训练之后保存模型,如果设置save_best_only=True,则保存最好的模型。
# 这里使用三个callback函数,TensorBoard, EarlyStopping, ModelCheckpoint
# Tensorboard需要一个文件夹存数据,ModelCheckpoint需要一个文件存数据
# logdir = './callbacks' 此处报错,改用下行
logdir = os.path.join("callbacks")
if not os.path.exists(logdir):
os.mkdir(logdir)
output_model_file = os.path.join(logdir, "fashion_mnist_model.h5")
callbacks = [
keras.callbacks.TensorBoard(logdir),
keras.callbacks.ModelCheckpoint(output_model_file, save_best_only = True), # save_best_only保存最好的模型,否则默认保存最近训练的模型
# 如果连续5次迭代的变化值都小于阈值min_delta,则停止训练
keras.callbacks.EarlyStopping(monitor='val_accuracy', patience=5, min_delta=1e-2)
]
# 开始训练 callbacks作为参数填入
history = model.fit(x_train_scaled, y_train, epochs=30, validation_data=(x_valid_scaled, y_valid), callbacks = callbacks)
构建深度神经网络DNN
深度网络模型就是层次多而已
#构建分类训练模型 深度神经网络
model = keras.models.Sequential()
# 先将数据展开
model.add(keras.layers.Flatten(input_shape=[28, 28]))
# 循环定义深度网络层 20层
for _ in range(20):
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer = 'sgd',
metrics = ["accuracy"])
model.summary()
批归一化
- 用keras.layers.BatchNormalization()来实现:
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
# 深度网络层 20层
for _ in range(20):
model.add(keras.layers.Dense(100, activation='relu'))
# 批归一化
model.add(keras.layers.BatchNormalization())
'''
# 另一种方式:将激活函数放在批归一化的后边,即先将输出进行归一化,再进行激活函数
model.add(keras.layers.Dense(100))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Activation='relu')
'''
model.add(keras.layers.Dense(10, activation='softmax'))
- 用selu激活函数来实现:
selu是自带归一化功能的激活函数,效果通常会比BatchNormalization()好一些
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
for _ in range(20):
model.add(keras.layers.Dense(100, activation='selu'))
model.add(keras.layers.Dense(10, activation='softmax'))
dropout
防止过拟合,一般只在最后几层添加,而不是每一层都添加dropout
在keras中dropout也被以一个层次的方式实现
model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[28, 28]))
# 循环定义深度网络层 20层
for _ in range(20):
model.add(keras.layers.Dense(100, activation='selu'))
# 在最后一层添加dropout,rate等于丢掉的比例,一般为0.5
model.add(keras.layers.AlphaDropout(rate=0.5))
# 传统的dropout:model.add(keras.layers.Dropout(rate=0.5))
# AlphaDropout相比于传统Dropout的优点:
# 1.均值和方差不变;2.归一化的性质不变,即可与selu或batchNormalization一起使用。故推荐使用AlphaDropout
model.add(keras.layers.Dense(10, activation='softmax'))