学习笔记:Keras中文文档
文章目录
基本概念
(1)张量
张量,或tensor,可以看作是向量、矩阵的自然推广,用张量来表示广泛的数据类型。
(2)数据格式(Data Format)
‘th’模式,比如一组彩色图片的数据表示,Theano会把100张RGB三通道的16×32(高为16,宽为32)彩色图表示为下面这种形式(100,3,16,32),即通道维靠前。
‘tf’模式
而TensorFlow的表达形式是(100,16,32,3),即把通道维放在了最后。
这种数据组织方式称为“channels last”,即通道维靠后。
(3)函数式模型(Functional Model)
Keras 模型的使用一般可以分为顺序模型或序贯模型(Sequential)和 Keras 函数式 API
顺序模型是多个网络层的线性堆叠,单输入单输出,一条路通到底,层与层之间只有相邻关系,跨层连接统统没有。这种模型编译速度快,操作上也比较简单。
而 Keras 函数式 API 是定义复杂模型(如多输出模型、有向无环图,或具有共享层的模型)的方法。
(4)batch(批数据)
引用:batch_size的含义
梯度下降时,每次参数更新有两种方式。
- 第一种,遍历全部数据集算一次损失函数,然后算函数对各个参数的梯度,更新梯度。这种方法每更新一次参数都要把数据集里的所有样本都看一遍,计算量开销大,计算速度慢,不支持在线学习,这称为Batch Gradient Descent,批梯度下降。
- 第二种,每看一个数据就算一下损失函数,然后求梯度更新参数,这个称为随机梯度下降(Stochastic Gradient Descent)。这个方法速度比较快,但是收敛性能不太好,可能在最优点附近抖动,命中不到最优点。两次参数的更新也有可能互相抵消掉,造成目标函数震荡的比较剧烈。
为了克服两种方法的缺点,现在一般采用的是一种折中手段,Mini-batch Gradient Decent(小批梯度下降)。
这种方法把数据分为若干个批,按批来更新参数,这样,一个批中的一组数据共同决定了本次梯度的方向,下降起来就不容易跑偏,减少了随机性。另一方面,因为批的样本数与整个数据集相比小了很多,计算量也减少了很多。
所以简单思考即可得出结论:
- batch尺寸越大,训练时表现得越像Batch Gradient Descent;
- batch尺寸越小,训练时表现得越像SGD,训练时抖动也越明显。
一般目前的梯度下降都是基于Mini-batch的,所以Keras的模块中经常会出现batch_size,正是指Mini-batch的大小。
(5)epochs:指的就是训练过程中整个数据集将被循环训练多少次。
keras入门学习笔记
keras模块思维导图
图片来源:https://blog.csdn.net/ice_actor/article/details/78290830
Keras的模块结构
图片来源:https://www.cnblogs.com/lc1217/p/7132364.html
使用Keras搭建一个神经网络
图片来源:https://www.cnblogs.com/lc1217/p/7132364.html
Sequential模型
Keras的核心数据结构是“模型”,模型是一种组织网络层的方式。
Keras中主要的模型是Sequential模型。Sequential是一系列网络层按顺序构成的栈。
全连接层
全连接网络(Full Connected,FC)是基础的深度学习模型,它的每一个神经元把前一层所有神经元的输出作为输入,其输出又会给下一层的每一个神经元作为输入,相邻层的每个神经元都有“连接”。
===
导包
import keras
# Sequential 顺序模型
from keras.models import Sequential
# Dense指全连接层
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD
import numpy as np
生成虚拟数据
x_train = np.random.random((1000, 20))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)
x_test = np.random.random((100, 20))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
模型初始化 ——序贯模型 或 顺序模型
model = Sequential ()
设计模型,通过add
的方式叠起来
注意输入时,初始网络(第一层)一定要给定输入的特征维度input_dim
或者input_shape
数据类型
activition
激活函数既可以在Dense
网络设置里,也可以单独添加
model.add(Dense(64,input_dim=20)) # 输入层
model.add(Activation ('relu')) # 第一隐藏层用 relu 作为激活函数
model.add(Dropout(0.5)) # 使用Dropout防止过拟合
model.add(Dense(64, activation='relu')) # 隐含层
model.add(Dropout(0.5)) # 使用Dropout防止过拟合
model.add(Dense(10, activation='softmax')) # 输出层
完成模型的搭建后,需要使用.compile()
方法来编译模型(配置)。
使用交叉熵作为Loss函数,优化器为SGD随机梯度下降法。
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) #定义求解算法
model.compile(loss='categorical_crossentropy',
optimizer=sgd,
metrics=['accuracy'])
# 编译模型时,必须指明损失函数和优化器,如果需要的话,也可以自定义损失函数。
# 或
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True))
epochs:指的就是训练过程中整个数据集将被循环训练多少次
batch_size,指Mini-batch的大小,每次参数更新方式,小批梯度下降
model.fit(x_train, y_train,
epochs=20,
batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128) # 测试模型 以 128 个样本为一个 batch 进行迭代
Keras用
- model.predict() 方法给出概率
- model.predict_classes() 方法给出分类结果。
Keras的一些基本实现
学习来源
整理笔记如下
(一) Keras 一元线性回归
import keras
from keras.layers import Dense
#Sequential 按顺序构成的模型
#Sequential是模型结构,输入层,隐藏层,输出层
from keras.models import Sequential
import numpy as np
import matplotlib.pyplot as plt
#-------------------------------------------准备数据-----------
#设置数据
x_data=np.random.rand(100)
#设置噪声
noise=np.random.normal(0,0.01,x_data.shape)
y_data=x_data*0.1+0.2+noise
#-------------------------------------------构建模型-----------
model=Sequential() #建立顺序模型序列
# 在模型中添加全连接层Dense
# ===> | ===>
model.add(Dense(units=1,input_dim=1)) #输入维度为1,输出维度为1
# 配置 损失函数 优化模型
model.compile(optimizer='sgd',loss='mse') #设置SGD优化模型,随机梯度下降
# 训练,迭代步为3001次。
for step in range(3001):
# 代价函数的值,其实就是loss
cost=model.train_on_batch(x_data,y_data) #batch 为每次训练的批次
if step%500 ==0:
print('cost:',cost) #每500次输出一次
# 打印权值和偏置值,这里只有一个层
w,b=model.layers[0].get_weights()
print("w:",w,"b:",b)
'''
cost: 0.05632266
cost: 0.008425701
cost: 0.0023607304
cost: 0.0007167198
cost: 0.00027108242
cost: 0.00015028476
cost: 0.00011754086
W: [[0.10844277]] b: [0.19684236]
'''
# 生成预测值
y_pred=model.predict(x_data)
# 可视化
plt.scatter(x_data,y_data)
plt.plot(x_data,y_pred,'r-',lw=3) #红色,长度为3
plt.show()
(二) Keras 非线性回归
import keras
import numpy as np
import matplotlib.pyplot as plt
#Sequential是模型结构,输入层,隐藏层,输出层
from keras.models import Sequential
#Dense 全连接层,Activation激活函数
from keras.layers import Dense,Activation
# 随机梯度下降
from keras.optimizers import SGD
# -------------------------------------------准备数据
x_data=np.linspace(-0.5,0.5,200)
noise=np.random.normal(0,0.02,x_data.shape)
y_data=np.square(x_data)+noise
plt.scatter(x_data,y_data)
plt.show()
# --------------------------------------------构造模型
#构建一个顺序模型
model=Sequential()
#1-10-1,添加一个隐藏层 即 (输入1)输入层(输出10) ==> (输入10)隐含层(输出1) ==> (输入1)输出层
model.add(Dense(units=10,input_dim=1,activation='tanh'))#units是隐藏层,输出维度,输出y,input_dim是输入维度,输入x
#model.add(Activation('relu'))#给这一层添加一个双曲正切激活函数tanh函数
model.add(Dense(units=1,input_dim=10,activation='tanh'))#input_dim可以不写,它可以识别到上一句的输出是10维
#model.add(Activation('relu'))#给这一层添加一个双曲正切激活函数tanh函数
#定义优化器
sgd=SGD(lr=0.3)#学习率提高到0.3,训练速度会加快
#配置
model.compile(optimizer=sgd,loss='mse')#编译这个模型,sgd是随机梯度下降法,优化器.mse是均方误差
#训练模型
for step in range(3001):
#每次训练一个批次
cost=model.train_on_batch(x_data,y_data)#代价函数的值,其实就是loss
#每500个batch打印一次cost值
if step %500==0:
print('cost:',cost)
#打印权值和偏置值
W,b=model.layers[0].get_weights()#线性回归,只有一层
print('W:',W,'b:',b)
'''
cost: 0.023039385676383972
cost: 0.00572865828871727
cost: 0.004948435351252556
cost: 0.002874723169952631
cost: 0.0006886456976644695
cost: 0.00039461225969716907
cost: 0.00038178107934072614
W: [[-0.18888883 -0.9140232 -0.72582877 0.13054956 -1.5954846 0.1890613
-0.12787792 -0.42756492 -0.8045884 0.12256911]]
b: [ 0.2681878 -0.3115701 -0.16136715 -0.32902387 0.7008824 -0.03654401
0.00578269 0.0130441 0.37201026 0.00775721]
'''
#x_data输入网络中,得到预测值y_pred
y_pred=model.predict(x_data)
#显示随机点s
plt.scatter(x_data,y_data)
#显示预测结果
plt.plot(x_data,y_pred,'r-',lw=3)#r-表示红色的线,lw表示线宽
plt.show()
(三)MNIST数据集分类
MNIST数据集是一个手写体数据集
import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
#载入数据
(x_train,y_train),(x_test,y_test)=mnist.load_data()
print('x_shape:',x_train.shape) # (60000,28,28)
print('y_shape:',y_train.shape) # (60000)
#(60000,28,28)->(60000,784)
x_train=x_train.reshape(x_train.shape[0],-1)/255.0 #除以255是归一化 -1指不确定,可以自动进行28X28 这里将-1写为784也可以,但一般写-1
x_test=x_test.reshape(x_test.shape[0],-1)/255.0
#换one_hot格式,把像素点转变成0、1形式
y_train=np_utils.to_categorical(y_train,num_classes=10)#数字为0-9,可把y_train分成10个类别
y_test=np_utils.to_categorical(y_test,num_classes=10)
#创建模型,输入784个神经元,输出10个神经元 784==>10
#激活函数softmax 将输出转为概率
model=Sequential([Dense(units=10,input_dim=784,bias_initializer='one',activation='softmax')])#bias_initializer='one',偏置值的初始值设为1
#定义优化器
sgd=SGD(lr=0.2)
#定义优化器,loss function,训练过程中计算准确率,也可以将随机梯度下降法mse改为categorical_crossentropy交叉熵函数
model.compile(optimizer=sgd, loss='mse',metrics=['accuracy'])#metrics指这里还可以计算准确率
#训练模型,可以用fit函数
#按batch计算在某些输入数据上模型的误差
#batch_size,指Mini-batch的大小,小批梯度下降,梯度下降时,每个batch包含的样本数。
#epochs:指的就是训练过程中整个数据集将被循环训练多少次。也即迭代的次数、训练的轮数
model.fit(x_train,y_train,batch_size=32,epochs=10)#从60000张图中每次拿32张来训练,要训练60000/32次,60000张图训练完叫一个周期,一共训练10个周期
#评估模型,用evaluate()函数
loss,accuracy=model.evaluate(x_test,y_test)
print('\ntest loss',loss)
print('accuracy',accuracy)
损失函数:交叉熵
改进
使用交叉熵收敛的速度较快,可以得到更好的效果
#创建模型,输入784个神经元,输出10个神经元 784==>10
#激活函数softmax 将输出转为概率
model=Sequential([Dense(units=10,input_dim=784,bias_initializer='one',activation='softmax')])#bias_initializer='one',偏置值的初始值设为1
#定义优化器
sgd=SGD(lr=0.2)
model.compile(optimizer=sgd,
loss='categorical_crossentropy',
metrics=['accuracy'])#metrics指这里还可以计算准确率
Dropout
改进
添加隐藏层,添加Dropout,防止过拟合
引用:深度学习中Dropout原理解析
输入是x输出是y,正常的流程是:我们首先把x通过网络前向传播,然后把误差反向传播以决定如何更新参数让网络进行学习。
Dropout可以比较有效的缓解过拟合的发生,在一定程度上达到正则化的效果。
Dropout说的简单一点就是:我们在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征,如图1所示。
Dropout(0.4)指的是让40%的神经元不工作,也即随机地将输入中40%的神经元激活为零。
关于dropout rate一般设置多大?
经验是决定dropout之前,需要先判断是否模型过拟合
先dropout=0, 训练后得到模型的一些指标(比如: F1, Accuracy, AP)。比较train数据集和test数据集的指标。
- 过拟合:尝试下面的步骤。
- 欠拟合:尝试调整模型的结构,暂时忽略下面步骤。
dropout设置成0.4-0.6之间, 再次训练得到模型的一些指标。
- 如果过拟合明显好转,但指标也下降明显,可以尝试减少dropout(0.2)
- 如果过拟合还是严重,增加dropout(0.2)
重复上面的步骤多次,就可以找到理想的dropout值了。
from keras.layers import Dense,Dropout
#创建模型,加入隐藏层,加入Dropout
#bias_initializer='one',偏置值的初始值设为1
#输入784,输出200 ==> 输入200,输出100 ==> 输入100,输出10
model=Sequential([Dense(units=200,input_dim=784,bias_initializer='one',activation='tanh'),
Dropout(0.4),
Dense(units=100,input_dim=200,bias_initializer='one',activation='tanh'),
Dropout(0.4),
Dense(units=10,input_dim=100,bias_initializer='one',activation='softmax')])
#从第二层开始, input_dim可以不写
# 激活函数activation='softmax',softmax一般放在神经网络最后一层,也就是输出层
#也可以用add()函数加隐藏层
'''
# 输入层有784个神经元
# 第一个隐层有200个神经元,激活函数为ReLu,Dropout比例为0.2
model.add(Dense(200, input_shape=(784,)))
model.add(Activation('relu'))
model.add(Dropout(0.2))
# 第二个隐层有100个神经元,激活函数为ReLu,Dropout比例为0.2
model.add(Dense(100))
model.add(Activation('relu'))
model.add(Dropout(0.2))
# 输出层有10个神经元,激活函数为SoftMax,得到分类结果
model.add(Dense(10))
model.add(Activation('softmax'))
# 输出模型的整体信息
# 总共参数数量为784*200+200 + 200*100+100 + 100*10+10 = 178110
model.summary()
'''
正则化
改进
添加隐藏层,添加正则化L2,防止过拟合
L1,L2正则化为什么能解决过拟合问题
正则化(Regularization)
L1和L2正则都是比较常见和常用的正则化项,都可以达到防止过拟合的效果。L1正则化的解具有稀疏性,可用于特征选择。L2正则化的解都比较小,抗扰动能力强。在求解过程中,L2通常倾向让权值尽可能小,最后构造一个所有参数都比较小的模型。因为一般认为参数值小的模型比较简单,能适应不同的数据集,也在一定程度上避免了过拟合现象。参数足够小,数据偏移得多一点也不会对结果造成什么影响,可以说“抗扰动能力强”。
什么时候加正则化,需要根据具体的问题 或者 具体的模型效果来看
import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
from keras.regularizers import l2#导入正则化函数L2
#载入数据
(x_train,y_train),(x_test,y_test)=mnist.load_data()
print('x_shape:',x_train.shape)#(60000,28,28)
print('y_shape:',y_train.shape)#(60000)
#(60000,28,28)->(60000,784)
x_train=x_train.reshape(x_train.shape[0],-1)/255.0 #除以255是归一化
x_test=x_test.reshape(x_test.shape[0],-1)/255.0
#换one_hot 格式,把像素点转变成0、1形式
y_train=np_utils.to_categorical(y_train,num_classes=10)#把y_train分成10个类别
y_test=np_utils.to_categorical(y_test,num_classes=10)
#创建模型,加入隐藏层,设置权值正则化L2,其实偏置值和激活值也可以设置正则化
#输入784,输出200 ==> 输入200,输出100 ==> 输入100,输出10
model=Sequential([Dense(units=200,input_dim=784,bias_initializer='one',activation='tanh',kernel_regularizer=l2(0.0003)),
Dense(units=100,input_dim=200,bias_initializer='one',activation='tanh',kernel_regularizer=l2(0.0003)),
Dense(units=10,input_dim=100,bias_initializer='one',activation='softmax',kernel_regularizer=l2(0.0003))])
'''
#也可以用add()函数加隐藏层
model.add(Dense(...))
model.add(Dense(...))
'''
#定义优化器,可以用SGD优化器,也可以用Adam优化器
sgd=SGD(lr=0.2)
#定义优化器,loss function,训练过程中计算准确率,二次代价函数改为categorical_crossentropy交叉熵函数
model.compile(optimizer=sgd, loss='categorical_crossentropy',metrics=['accuracy'])#这里还可以计算准确率
#训练模型,可以用fit函数
model.fit(x_train,y_train,batch_size=32,epochs=10)#从60000张图中每次拿32张来训练,60000张图训练完叫一个周期,一共训练10个周期
#评估模型,用evaluate()函数
loss,accuracy=model.evaluate(x_test,y_test)
print('\ntest loss',loss)
print('test accuracy',accuracy)
loss,accuracy=model.evaluate(x_train,y_train)
print('\ntrain loss',loss)
print('train accuracy',accuracy)
优化器 (optimizer) SGD、ADM
优化器 (optimizer) 是编译 Keras 模型的所需的两个参数之一
引自:https://blog.csdn.net/u013249853/article/details/89148990
优化器是向模型打包传递参数,什么参数呢,就是我们训练时使用到的诸如,学习率,衰减,momentum,梯度下降得到若干种方式,用不用动量等等。你可以在一开始传入这个值,然后就一直使用这个值训练,也可以在训练时根据epoch调整参数。
也可以理解为
优化器是调整每个节点权重的方法
学习以及图片来源:keras学习笔记(3)—优化器
optimizers.SGD(lr=0.001,momentum=0.9)
optimizers.Adagrad(lr=0.01,epsilon=1e-8)
optimizers.Adadelta(lr=0.01,rho=0.95,epsilon=1e-8)
optimizers.RMSprop(lr=0.001,rho=0.9,epsilon=1e-8)
optimizers.Adam(lr=0.001,beta_1=0.9,beta_2=0.999,epsilon=1e-8)
原作者提到:当不知道选择哪种算法好的时候就选择Adam。
除此之外
如何选择优化器 optimizer
import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD,Adam
from keras.regularizers import l2#导入正则化函数L2
#载入数据
(x_train,y_train),(x_test,y_test)=mnist.load_data()
print('x_shape:',x_train.shape)#(60000,28,28)
print('y_shape:',y_train.shape)#(60000)
#(60000,28,28)->(60000,784)
x_train=x_train.reshape(x_train.shape[0],-1)/255.0 #除以255是归一化
x_test=x_test.reshape(x_test.shape[0],-1)/255.0
#换one_hot 格式,把像素点转变成0、1形式
y_train=np_utils.to_categorical(y_train,num_classes=10)#把y_train分成10个类别
y_test=np_utils.to_categorical(y_test,num_classes=10)
#创建模型,加入隐藏层,设置权值正则化L2,其实偏置值和激活值也可以设置正则化
#输入784,输出200 ==> 输入200,输出100 ==> 输入100,输出10
model=Sequential([Dense(units=200,input_dim=784,bias_initializer='one',activation='tanh',kernel_regularizer=l2(0.0003)),
Dense(units=100,input_dim=200,bias_initializer='one',activation='tanh',kernel_regularizer=l2(0.0003)),
Dense(units=10,input_dim=100,bias_initializer='one',activation='softmax',kernel_regularizer=l2(0.0003))])
'''
#也可以用add()函数加隐藏层
model.add(Dense(...))
model.add(Dense(...))
'''
#定义优化器,可以用SGD优化器,也可以用Adam优化器
# sgd=SGD(lr=0.2)
adam=Adam(lr=0.001)#lr是学习率
#定义优化器,loss function,训练过程中计算准确率,二次代价函数改为categorical_crossentropy交叉熵函数
model.compile(optimizer=sgd, loss='categorical_crossentropy',metrics=['accuracy'])#这里还可以计算准确率
#训练模型,可以用fit函数
model.fit(x_train,y_train,batch_size=32,epochs=10)#从60000张图中每次拿32张来训练,60000张图训练完叫一个周期,一共训练10个周期
#评估模型,用evaluate()函数
loss,accuracy=model.evaluate(x_test,y_test)
print('\ntest loss',loss)
print('test accuracy',accuracy)
loss,accuracy=model.evaluate(x_train,y_train)
print('\ntrain loss',loss)
print('train accuracy',accuracy)
(四)CNN应用于手写数字识别
import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
# Convolution2D做二维卷积;
# MaxPooling2D二维的最大池化;
# Flatten把数据扁平化,降维,如下面的数据变换过程
from keras.layers import Dense,Dropout,Convolution2D,MaxPooling2D,Flatten
from keras.optimizers import SGD,Adam#导入SGD优化器,Adam优化器
#载入数据
(x_train,y_train),(x_test,y_test)=mnist.load_data()
#(60000,28,28)
#print('x_shape:',x_train.shape)
#(60000)
#print('y_shape:',y_train.shape)
#转化为4维
#最后一个维度图片深度,1表示黑白,3表示彩色
#rgb是红绿蓝三通道0-255表示各个通道的颜色深度
#(60000,28,28)->(60000,28,28,1)
#-1表示自动设置
#除以255是做数据归一化处理
x_train=x_train.reshape(-1,28,28,1)/255.0 #除以255是归一化
x_test=x_test.reshape(-1,28,28,1)/255.0
#换one_hot 格式,把像素点转变成0、1形式
y_train=np_utils.to_categorical(y_train,num_classes=10)#把y_train分成10个类别
y_test=np_utils.to_categorical(y_test,num_classes=10)
#定义模型
model=Sequential()
#定义第一个卷积层
#input_shape输入平面
#filters 卷积核/滤波器个数
#kernel_size 卷积窗口的大小
#strides步长
#padding padding方式same/valid
#activation激活函数
model.add(Convolution2D(
input_shape=(28,28,1),#只需要在第一次添加输入平面
filters=32,
kernel_size=5,
strides=1,
padding='same',
activation='relu'
))
#平面大小28x28,用same padding得到的和上一次一样,也是28x28,有32个特征图
#池化后变成14x14,32个特征图
#第一个池化层
model.add(MaxPooling2D(
pool_size=2, # 池化窗口大小 2x2的窗口
strides=2,
padding='same'
))
#第二个卷积层
#64个卷积核,卷积窗口的大小5,步长1,padding方式,激活函数relu
model.add(Convolution2D(64,5,strides=1,padding='same',activation='relu'))
#第二个卷积层后64个特征图,14x14
#第二个池化层后64个特征图,7x7
#第二个池化层
model.add(MaxPooling2D(2,2,'same'))
#把第二个池化层的输出扁平化为1维
#长度 64x7x7
#把第二个池化层的输出扁平化为1维
model.add(Flatten())
#第一个全连接层
model.add(Dense(1024,activation='relu'))
#Dropout
#50%的神经元不工作
model.add(Dropout(0.5))
#第二个全连接层
model.add(Dense(10,activation='softmax'))
#定义优化器
#sgd=SGD(lr=0.2)
adam=Adam(lr=0.001)#lr是学习率
#定义优化器,loss function,训练过程中计算准确率,二次代价函数改为categorical_crossentropy交叉熵函数
model.compile(optimizer=adam,
loss='categorical_crossentropy' #损失用交叉熵,速度会更快
,metrics=['accuracy'])#这里还可以计算准确率
#训练模型,可以用fit函数
##六万张,每次训练64张,训练10个周期(六万张全部训练完算一个周期)
#迭代10次
model.fit(x_train,y_train,batch_size=64,epochs=10)#从60000张图中每次拿64张来训练,60000张图训练完叫一个周期,一共训练10个周期
#评估模型,用evaluate()函数
loss,accuracy=model.evaluate(x_test,y_test)
print('\ntest loss',loss)
print('test accuracy',accuracy)
loss,accuracy=model.evaluate(x_train,y_train)
print('\ntrain loss',loss)
print('train accuracy',accuracy)
(五)RNN的应用
import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.layers.recurrent import SimpleRNN
from keras.optimizers import Adam
# 数据长度-一行有28个像素
input_size = 28
# 序列长度-一共有28行
time_steps = 28
# 隐藏层cell个数
cell_size = 50
# 载入数据
(x_train,y_train),(x_test,y_test) = mnist.load_data()
# (60000,28,28)
# 60000代表总的样本数
# 28代表一个样本有多少的序列
# 28代表在每个序列中序列长度为多少
x_train = x_train/255.0
x_test = x_test/255.0
# 换one hot格式
y_train = np_utils.to_categorical(y_train,num_classes=10)
y_test = np_utils.to_categorical(y_test,num_classes=10)#one hot
# 创建模型
model = Sequential()
# 循环神经网络
model.add(SimpleRNN(
units = cell_size, # 输出
input_shape = (time_steps,input_size), #输入
))
# 输出层
model.add(Dense(10,activation='softmax'))
# 定义优化器
adam = Adam(lr=1e-4)
# 定义优化器,loss function,训练过程中计算准确率
model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy'])
# 训练模型
model.fit(x_train,y_train,batch_size=64,epochs=10)
# 评估模型
loss,accuracy = model.evaluate(x_test,y_test)
print('test loss',loss)
print('test accuracy',accuracy)
(六)模型的保存和载入
keras的模型一般保存为后缀名为h5的文件,比如final_model.h5
保存
model.save('model.h5')
载入
from keras.models import load_model
model = load_model('m1.h5')
#model = load_model('m2.h5')
#model = load_model('m3.h5')
model.summary()
载入之后,还可以继续训练
除此之外
keras保存模型中的save()和save_weights()
(七)绘制网络结构
import numpy as np
from keras.datasets import mnist #将会从网络下载mnist数据集
from keras.utils import np_utils
from keras.models import Sequential #序列模型
#Convolution2D 是2维卷积
#MaxPooling2D 是2维最大池化
#Flatten 数据扁平化(降维)
from keras.layers import Dense,Dropout,Convolution2D,MaxPooling2D,Flatten #在这里导入dropout
from keras.optimizers import Adam
from keras.utils.vis_utils import plot_model
import matplotlib.pyplot as plt
import tensorflow as tf
#需要安装pydot和graphviz
#graphviz需要在官网安装,安装后需要添加环境变量,程序所在目录的bin文件夹加入系统变量
#载入数据
(x_train,y_train),(x_test,y_test)=mnist.load_data()
#查看格式
#(60000,28,28)
print('x_shape:',x_train.shape)
#(60000)
print('y_shape:',y_train.shape)
#转化为4维
#最后一个维度图片深度,1表示黑白,3表示彩色
#rgb是红绿蓝三通道0-255表示各个通道的颜色深度
#(60000,28,28)->(60000,28,28,1)
#-1表示自动设置
#除以255是做数据归一化处理
x_train=x_train.reshape(-1,28,28,1)/255.0 #转换数据格式
x_test=x_test.reshape(-1,28,28,1)/255.0 #转换数据格式
#label标签转换成 one hot 形式
y_train=np_utils.to_categorical(y_train,num_classes=10) #分成10类
y_test=np_utils.to_categorical(y_test,num_classes=10) #分成10类
#定义序列模型
model=Sequential()
#第一个卷积层
#input_shape 输入平面
#filters 卷积核/滤波器个数
#kernel_size 卷积窗口大小
#strides 步长
#padding padding方式 same/valid
#activation 激活函数
model.add(Convolution2D(
input_shape=(28,28,1),#只需要在第一次添加输入平面
filters=32,
kernel_size=5,
strides=1,
padding='same',
activation='relu'
))
#平面大小28x28,用same padding得到的和上一次一样,也是28x28,有32个特征图
#池化后变成14x14,32个特征图
#第一个池化层
model.add(MaxPooling2D(
pool_size=2, # 池化窗口大小 2x2的窗口
strides=2,
padding='same'
))
#第二个卷积层
#filters=64 kernel_seize=5
model.add(Convolution2D(64,5,strides=1,padding='same',activation='relu'))
#第二个卷积层后64个特征图,14x14
#第二个池化层后64个特征图,7x7
#第二个池化层
model.add(MaxPooling2D(2,2,'same'))
#把第二个池化层的输出扁平化为1维
#长度 64x7x7
model.add(Flatten())
#第一个全连接层
#1024个神经元
model.add(Dense(1024,activation='relu'))
#Dropout
#训练时百分之40个神经元不工作
model.add(Dropout(0.4))
#第二个全连接层
model.add(Dense(10,activation=(tf.nn.softmax)))
##定义优化器
##学习速率为10的负4次方
#adam=Adam(lr=1e-4)
#
#
##定义优化器,损失函数,训练效果中计算准确率
#model.compile(
# optimizer=adam, #sgd优化器
# loss='categorical_crossentropy', #损失用交叉熵,速度会更快
# metrics=['accuracy'], #计算准确率
#)
#
##训练
##六万张,每次训练64张,训练10个周期(六万张全部训练完算一个周期)
#model.fit(x_train,y_train,batch_size=64,epochs=10)
#
##评估模型
#loss,accuracy=model.evaluate(x_test,y_test)
#
#print('\ntest loss',loss)
#print('\ntest accuracy',accuracy)
#
#loss,accuracy=model.evaluate(x_train,y_train)
#
#print('\ntrain loss',loss)
#print('\ntrain accuracy',accuracy)
#TB代表从上往下,LR表示从左往右
plot_model(model,to_file='model.png',show_shapes=True,show_layer_names='False',rankdir='TB')
plt.figure(figsize=(20,20))
img=plt.imread('model.png')
plt.imshow(img)
plt.axis('off')
plt.show()
比如,前面的CNN 绘制出来的网络结构如下