一、主程序

main.py

""" 参考:https://zhuanlan.zhihu.com/p/59986254 Link: www.kaikai.ai Github: github.com/loveunk 这是一个完整的mnist分类demo,其中涉及的技术点包括: 1. TensorFlow dataset minist的加载 2. 数据直方图打印 3. 数据归一化 4. label数据的 one hot vectors转换 5. 数据集切分(train、test) 6. CNN 模型创建 7. 保存模型图片 8. 图片数据增强 9. 绘制训练集和验证集的loss和accuracy曲线 10. 使用TensorBoard 11. 对测试集做预测 12. 对prediction的one-hot vector转换为数字 13. 计算Precision、recall、F1等 可以作为入门TensorFlow/Keras的例子。 测试环境:TensorFlow:1.13.1 """

import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import seaborn as sns

np.random.seed(13)
sns.set(style='white', context='talk', palette='deep')

(X_train, Y_train), (X_test, Y_test) = tf.keras.datasets.mnist.load_data()

# 看看数据的shape
print(X_train.shape)
print(Y_train.shape)

# 画一个数据集的例子来看看
plt.imshow(X_train[0][:,:])
plt.show()

# 打印数据的直方图
sns.countplot(Y_train)
plt.show()

# 归一化数据,让CNN更快
X_train = X_train / 255.0
X_test = X_test / 255.0

X_train = X_train.reshape(-1, 28, 28, 1)
X_test = X_test.reshape(-1, 28, 28, 1)

# 把label转换为one hot vectors (ex : 2 -> [0,0,1,0,0,0,0,0,0,0])
Y_train = tf.keras.utils.to_categorical(Y_train, num_classes=10)

X_train, X_val, Y_train, Y_val = train_test_split(X_train,
                                                  Y_train,
                                                  test_size=0.1,
                                                  random_state=2)


# 创建CNN model
# 模型:
""" [[Conv2D->relu]*2 -> BatchNormalization -> MaxPool2D -> Dropout]*2 -> [Conv2D->relu]*2 -> BatchNormalization -> Dropout -> Flatten -> Dense -> BatchNormalization -> Dropout -> Out """
model = tf.keras.Sequential()

model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=(5,5), padding='Same', activation='relu', input_shape = (28,28,1)))
model.add(tf.keras.layers.BatchNormalization())

model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=(5,5), padding='Same', activation='relu'))
model.add(tf.keras.layers.BatchNormalization())

model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))
model.add(tf.keras.layers.Dropout(0.25))

model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=(3,3),padding='Same', activation='relu'))
model.add(tf.keras.layers.BatchNormalization())

model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=(3,3),padding='Same', activation='relu'))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2)))
model.add(tf.keras.layers.Dropout(0.25))

model.add(tf.keras.layers.Conv2D(filters=64, kernel_size=(3,3), padding='Same', activation='relu'))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Dropout(0.25))

model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(256, activation="relu"))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Dropout(0.25))

model.add(tf.keras.layers.Dense(10, activation="softmax"))

# 打印出model 看看
# tf.keras.utils.plot_model(model, to_file='model.png', show_shapes=True, show_layer_names=True)
# plt.imshow(mpimg.imread('model.png'))
plt.show()

# 定义Optimizer
optimizer = tf.keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)

# 编译model
model.compile(optimizer=optimizer, loss="categorical_crossentropy", metrics=["accuracy"])

# 设置学习率的动态调整
learning_rate_reduction = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_acc',
                                                               patience=3,
                                                               verbose=1,
                                                               factor=0.5,
                                                               min_lr=0.00001)

# should add early_stopping to the model training callbacks later
early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', restore_best_weights=True)

# 设置epochs和batch size
epochs = 3
batch_size = 64

# 通过数据增强来防止过度拟合
datagen = tf.keras.preprocessing.image.ImageDataGenerator(
        featurewise_center=False, # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)
        zoom_range = 0.1, # Randomly zoom image
        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=False,  # randomly flip images
        vertical_flip=False)  # randomly flip images
datagen.fit(X_train)

# 训练模型
history = model.fit_generator(datagen.flow(X_train, Y_train, batch_size=batch_size),
                              epochs=epochs,
                              validation_data=(X_val, Y_val),
                              verbose=2,
                              steps_per_epoch=X_train.shape[0] // batch_size,
                              callbacks=[learning_rate_reduction, early_stopping, tf.keras.callbacks.TensorBoard(log_dir='./log_dir')])

# 画训练集和验证集的loss和accuracy曲线。可以判断是否欠拟合或过拟合
fig, ax = plt.subplots(2, 1)
ax[0].plot(history.history['loss'], color='b', label="Training loss")
ax[0].plot(history.history['val_loss'], color='r', label="validation loss", axes =ax[0])
legend = ax[0].legend(loc='best', shadow=True)

ax[1].plot(history.history['acc'], color='b', label="Training accuracy")
ax[1].plot(history.history['val_acc'], color='r',label="Validation accuracy")
legend = ax[1].legend(loc='best', shadow=True)
plt.show()

# 对测试集做预测
results = model.predict(X_test)

# 把one-hot vector转换为数字
Y_pred = np.argmax(results, axis=1)

print("precision = ", precision_score(Y_test, Y_pred, average="macro"))
print("recall = ", recall_score(Y_test, Y_pred, average="macro"))
print("f1_score = ", f1_score(Y_test, Y_pred, average="macro"))
print("accuracy = ", accuracy_score(Y_test, Y_pred))

生成新文件之后,总的文件树如下:

-- my_code
	-- main.py
	-- log_dir
		-- events.out.tfevents.1609922043

二、运行 Tensorboard

接下来,在pycharm的terminal中,在 my_code 路径下:
运行:

tensorboard --logdir="./log_dir"

输出:

TensorBoard 1.13.1 at http://C02D70PKMD6R:6007 (Press CTRL+C to quit)

三、在谷歌浏览器输入

http://localhost:6007/

⚠️ 运行 tensorboard 输出的端口可能是 6006,也可能是 6007,具体视情况而定

四、 只有meta 文件

import tensorflow as tf
g = tf.Graph() 
with g.as_default() as g: 
    tf.train.import_meta_graph('criteo_80.meta') 
 
with tf.Session(graph=g) as sess: 
    file_writer = tf.summary.FileWriter(logdir='./', graph=g)

即可生成文件:events.out.tfevents.1609922043
再运行 Tensorboard 即可

参考:

  1. TensorFlow可视化工具TensorBoard
  2. tensorflow 利用保存的meta图文件生成log供tensorboard可视化 保存恢复模型