之前一直用的是TensorFlow,但是一用Keras之后就立马被它圈粉,Keras对于函数的封装十分得精炼。
先上代码

导入模块

import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ReduceLROnPlateau
from keras.callbacks import TensorBoard
from keras.callbacks import ModelCheckpoint
from keras.models import load_model
import os
import warnings
# 忽略硬件加速的警告信息
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
warnings.filterwarnings('ignore')

导入训练和测试数据

X_train = np.random.random((1000, 28, 28, 1))
print(X_train.shape)
#这里的数据模仿的是图片数据
y_train = keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)
#这些照片总共有10个类别
print(y_train.shape)
X_test = np.random.random((100, 28, 28, 1))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)

(1000, 28, 28, 1)的意思是说有1000张测试图片,它们的width, height,channel分别为28,28,1,属于灰度图片。这些照片总共有10个类别,使用keras.utils.to_categorical将类别信息转换为独热码的形式(独热码有利于神经网络的训练)

batch_size=28    #每次喂给网络28组数据
epochs=2

一共进行2轮。这里的意思也就是说1000张图片,每次训练28张,所以需要训练1000÷28=35次余20个,相当于一共训练36次,只不过最后一次只喂了20组数据给网络。当最后20个数据喂完后,1个epoch就结束了,然后再回到这1000张图片的第一张,从头开始继续训练。

建立模型

model = Sequential() #这里使用序贯模型,比较容易理解
#序贯模型就像搭积木一样,将神经网络一层一层往上搭上去
model.add(Conv2D(32, (3, 3), activation='relu', padding='same', data_format='channels_last',name='layer1_con1',input_shape=(28, 28, 1)))
#搭一个卷积层
model.add(Conv2D(32, (3, 3), activation='relu', padding='same', data_format='channels_last',name='layer1_con2'))
#再搭一层卷积层效果更好
model.add(MaxPooling2D(pool_size=(2, 2),strides=(2,2), padding = 'same', data_format='channels_last',name = 'layer1_pool'))
#搭一个最大池化层
model.add(Dropout(0.25))
#dropout层可以防止过拟合,每次有25%的数据将被抛弃

这里搭建的卷积层共有32个卷积核,卷积核大小为3*3,采用relu的激活方式。这里的data_format='channels_last’意思是通道数在最后,因为我之前的图片数据就是(100, 28, 28, 1),最后那个1就是通道数,普通的照片是3通道的,就是有RGB三种颜色,我生成的是灰度图。这里的name就是给这层卷积层的命名,给它一个名字。这样的好处在使用tensorboard后非常的明显。input_shape,字面意思就是输入数据的维度。

model.add(Conv2D(64, (3, 3), activation='relu', padding='same', data_format='channels_last',name='layer2_con1'))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same', data_format='channels_last',name='layer2_con2'))
model.add(MaxPooling2D(pool_size=(2, 2),strides=(2,2), padding = 'same', data_format='channels_last',name = 'layer2_pool'))
#和上面的网络结构类似

最后的全连接层

model.add(Flatten())
model.add(Dense(128, activation='relu'))  #该全连接层共128个神经元
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax')) 
#一共分为10类,所以最后一层有10个神经元,并且采用softmax输出

模型编译

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics = ['accuracy'])
#定义损失值、优化器

回调函数Callbacks

learning_rate_reduction = ReduceLROnPlateau(monitor = 'val_acc', patience = 3,mode='auto',  verbose = 1, factor=0.5, min_lr = 0.00001)

当评价指标不再提升时,减少学习率。当学习停滞时,减少2倍或10倍的学习率常常能获得较好的效果。该回调函数检测指标的情况,如果在patience个epoch中看不到模型性能提升,则减少学习率。此处patience=3,也就是说,当模型训练了3个epoch后,模型准确率还没有提升,就减小学习率

https://keras-cn.readthedocs.io/en/latest/other/callbacks/

#TensorBoard可视化
TensorBoard=TensorBoard(log_dir='./log', write_images=1, histogram_freq=1)

TensorBoard是一款非常好的可视化利器。在cmd窗口输入tensorboard --logdir=log文件路径,即可获得tensorboard的地址。此处tensorboard的log文件存入log这个文件夹里

#保存训练参数
Checkpoint=ModelCheckpoint(filepath='./cnn_model',monitor='val_acc',mode='auto' ,save_best_only=True)

图片增强

data_augment = ImageDataGenerator(rotation_range= 10,zoom_range= 0.1,
                                  width_shift_range = 0.1,height_shift_range = 0.1,
                                  horizontal_flip = False, vertical_flip = False)

将原始图片通过旋转放大等操作,获得更多的数据集,同时也增加了模型的鲁棒性

模型训练

model.fit_generator(data_augment.flow(X_train, y_train, 
batch_size=batch_size),epochs= epochs, validation_data = (X_test,y_test),     
verbose=5,callbacks=[learning_rate_reduction,TensorBoard,Checkpoint],shuffle=True)

模型评估

[loss,accuracy] = model.evaluate(X_test, y_test)
print('\nTest Loss: ', loss)
print('\nTest Accuracy: ', accuracy)

总之Keras还是比较容易上手的,不过一开始可以试试TensorFlow,虽然繁琐,但对于网络的构建能够更深入的理解。当然,如果用C语言写,那就再好不过了,从上到下敲完一遍神经网络,直接就升华了。。。

完整代码:
https://github.com/lubu-Alex/My_keras 里面还有Keras迁移学习以及预测的代码

参考资料:
https://keras-cn.readthedocs.io/en/latest/getting_started/sequential_model/