小弟最近自学机器学习,代码大部分参考福州大学江老师的视频,链接在https://www.bilibili.com/video/BV1zE411V79p?p=40
做了一点点自己的改进,希望能和大家分享,一起学习。
import numpy as np
from os import listdir
from keras.utils.np_utils import to_categorical #独热编码
from keras.layers import Input,Dense,Flatten,Dropout #输入层,全连接层,平铺层,Dropout
from keras.models import Model
import matplotlib.pyplot as plt
from keras.callbacks import ModelCheckpoint #模型检查点模块;选择、保存模型
from keras.callbacks import EarlyStopping #让模型对精度进行判断,是否一直未变,可以提前退出迭代。
from keras.callbacks import ReduceLROnPlateau #自动调整学习率
from keras.models import load_model #加载模型
modelfilepath = 'model.best.hdf5' #通常深度学习的文件保存为.hdf5格式
#固定随机数种子,使代码结果可以复现,每次都一样
seed = 42
np.random.seed(seed)
def img2vector(filename): #图片转成向量(32*32维)
fr = open(filename)
vector = np.zeros((32,32))
for i in range(32):
listStr = fr.readline()
for j in range(32):
vector[i, j] = int(listStr[j])
return vector
trainingMat = []
hwLabels = []
trainingFilelist = listdir('trainingDigits') #用于返回指定文件夹包含的文件或文件夹的名字的列表。
m = len(trainingFilelist)
for i in range(m):
fileNameStr = trainingFilelist[i]
fileStr = fileNameStr.split('.')[0]
classNumStr = int(fileStr.split('_')[0])
hwLabels.append(to_categorical(classNumStr, 10))
trainingMat.append(img2vector('trainingDigits/%s' % fileNameStr))
trainX = np.array(trainingMat)
trainY = np.array(hwLabels)
#将训练集的数据和吧标签随机打乱:由于数据是按顺序排的,解决了训练集表现好、验证集表现差、测试集表现略差的问题。
np.random.seed(200)
np.random.shuffle(trainX)
np.random.seed(200)
np.random.shuffle(trainY)
#配置神经网络
inp = Input(shape = (32,32))
x = Flatten(name='flatten')(inp)
x = Dense(400, activation='relu', name='dense-1')(x)
x = Dropout(0.2, name='dropout-1')(x) #该函数随机的丢弃一些网络节点,防止过拟合,随机删除20%
x = Dense(10, activation='softmax', name='recognition')(x)
model = Model(inp, x)
model.compile(optimizer='adam', loss='mse', metrics=['accuracy'])
model.summary() #查看网络结构
#定义一个模型选择函数,modelfilepath为文件名monitor为监视的参量;verbose指保存时打出文字,日志显示有更准确的量出现;
#save_best_only指是否只保留一个最好的模型,其他丢弃;mode指监视的参量的选择模式。
checkpoint = ModelCheckpoint(modelfilepath, monitor='val_accuracy', verbose=1,
save_best_only=True, mode='max')
#自动停止训练,patience为容忍次数;
earlyStop = EarlyStopping(monitor='val_accuracy', patience=20, verbose=1, mode='auto')
#自动调整学习率,factor表示当调整时学习率*factor,min_delta表示学习率的最小变化量,cooldown表示需要冷静的次数,min_lr表示最小的学习率。
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=1, mode='auto',
min_delta=0.00001, cooldown=0, min_lr=0)
history = model.fit(trainX, trainY, validation_split=0.1, epochs=100, batch_size=32, callbacks=[checkpoint, earlyStop, reduce_lr])
#callback指嵌入模型(hdf5文件)
testmodel = load_model(modelfilepath)#加载模型
#测试!
testFileList = listdir('testDigits')
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0]
classNumStr = int(fileStr.split('_')[0])
vectorUnderTest= img2vector('trainingDigits/%s' % fileNameStr)
testVector = []
testVector.append(vectorUnderTest)
testX = np.array(testVector)
classfierResult = np.argmax(testmodel.predict(testX)) #argmax找出最大元素的索引
print("DNN得到的辨识结果是: %d,实际值是: %d" % (classfierResult, classNumStr))
if classfierResult != classNumStr:
errorCount += 1.0
print("\n辨识错误数量为:%d" % errorCount)
print("\n辨识率为:%f %" % ((1-errorCount/float(mTest))*100))
#画出训练图形
plt.plot(history.history['loss']) #不大懂
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Val'], loc='upper left')
plt.show()
问题:
出现过的一个小问题,数据集是按顺序排列的,需要将训练集的数据和吧标签随机打乱:由于数据是按顺序排的,会出现训练集表现好、验证集表现差、测试集表现略差的问题。