【Keras篇】---Keras初始,两种模型构造方法,利用keras实现手写数字体识别
一、前述
Keras 适合快速体验 ,keras的设计是把大量内部运算都隐藏了,用户始终可以用theano或tensorflow的语句来写扩展功能并和keras结合使用。
二、安装
Pip install --upgrade keras
三、Keras模型之序列模型
序列模型属于通用模型的一种,因为很常见,所以这里单独列出来进行介绍,这种模型各层之间是依次顺序的线性关系,在第k层和第k+1层之间可以加上各种元素来构造神经网络
这些元素可以通过一个列表来制定,然后作为参数传递给序列模型来生成相应的模型。
第一种方式
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Activation # Dense相当于构建一个全连接层,32指的是全连接层上面神经元的个数
layers = [Dense(32, input_shape=(784,)),
Activation('relu'),
Dense(10),
Activation('softmax')]
model = Sequential(layers)
model.summary()
第二种方式:
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Activation model = Sequential()
model.add(Dense(32, input_shape=(784,)))
model.add(Activation('relu'))
model.add(Dense(10))
model.add(Activation('softmax'))
结果:
四、Keras模型之通用模型
通用模型可以用来设计非常复杂、任意拓扑结构的神经网络,例如有向无环图网络类似于序列模型,通用模型通过函数化的应用接口来定义模型使用函数化的应用接口有好多好处,比如:决定函数执行结果的唯一要素是其返回值,而决定返回值的唯一要素则是其参数,这大大减轻了代码测试的工作量
在通用模型中,定义的时候,从输入的多维矩阵开始,然后定义各层及其要素,最后定义输出层将输入层和输出层作为参数纳入通用模型中就可以定义一个模型对象
代码:
# 通用模型
# 通用模型可以用来设计非常复杂、任意拓扑结构的神经网络,例如有向无环图网络
# 类似于序列模型,通用模型通过函数化的应用接口来定义模型
# 使用函数化的应用接口有好多好处,比如:决定函数执行结果的唯一要素是其返回值,而决定
# 返回值的唯一要素则是其参数,这大大减轻了代码测试的工作量 # 在通用模型中,定义的时候,从输入的多维矩阵开始,然后定义各层及其要素,最后定义输出层
# 将输入层和输出层作为参数纳入通用模型中就可以定义一个模型对象 from keras.layers import Input
from keras.layers import Dense
from keras.models import Model # 定义输入层
input = Input(shape=(784,))
# 定义各个连接层,假设从输入层开始,定义两个隐含层,都有64个神经元,都使用relu激活函数
x = Dense(64, activation='relu')(input)#把上一层输出结果给下一层的输入
x = Dense(64, activation='relu')(x)
# 定义输出层,使用最近的隐含层作为参数
y = Dense(10, activation='softmax')(x)#整个逻辑从输入到输出全都在y里面了 # 所有要素都齐备以后,就可以定义模型对象了,参数很简单,分别是输入和输出,其中包含了
# 中间的各种信息
model = Model(inputs=input, outputs=y) # 当模型对象定义完成之后,就可以进行编译(定义损失函数,通过什么方式优化(优化器),等等)了,并对数据进行拟合,拟合的时候也有两个参数
# 分别对应于输入和输出
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(data, labels)#data是输入数据的X labels是Y
五、Keras实现手写识别体案例
import numpy as np
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
#Conv2D 图片是3通道 Conv1D 单声道或者双声道 # 先读入数据
(X_train, y_train), (X_test, y_test) = mnist.load_data("../test_data_home")
# 看一下数据集的样子
print(X_train[0].shape)#X_train是很多张图片[0]是第一张
print(y_train[0]) # 下面把训练集中的手写黑白字体变成标准的四维张量形式,即(样本数量,长,宽,1)
# 1是channel通道
# 并把像素值变成浮点格式
# X_train.shape[0]取得是行的数量
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32')
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32') # 由于每个像素值都介于0到255,所以这里统一除以255,把像素值控制在0-1范围
X_train /= 255 #X_train是一个矩阵 这里相当于里面每个数都除以255
X_test /= 255 # 由于输入层需要10个节点,所以最好把目标数字0-9做成One Hot编码的形式
def tran_y(y):#自己定义的One_hot编码格式 先定义10个零 然后在对应个数上填1
y_ohe = np.zeros(10)
y_ohe[y] = 1
return y_ohe # 把标签用One Hot编码重新表示一下
y_train_ohe = np.array([tran_y(y_train[i]) for i in range(len(y_train))])#列表生成器
y_test_ohe = np.array([tran_y(y_test[i]) for i in range(len(y_test))]) # 搭建卷积神经网络
model = Sequential()
# 添加一层卷积层,构造64个过滤器(卷积核),每个过滤器(卷积核)覆盖范围是3*3*1
# 过滤器步长为1,图像四周补一圈0,并用relu进行非线性变化
model.add(Conv2D(filters=64, kernel_size=(3, 3), strides=(1, 1), padding='same',
input_shape=(28, 28, 1), activation='relu'))#activation如果不设置,就是线性的
# 添加一层最大池化层
model.add(MaxPooling2D(pool_size=(2, 2)))#默认Strides是和池化维度一样 这里是2*2 池化默认一般不做padding
# 设立Dropout层,Dropout的概率为0.5
model.add(Dropout(0.5)) # 重复构造,搭建深度网络
model.add(Conv2D(128, kernel_size=(3, 3), strides=(1, 1), padding='same',
activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Conv2D(256, kernel_size=(3, 3), strides=(1, 1), padding='same',
activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5)) # 把当前层节点展平
model.add(Flatten()) # 构造全连接层神经网络层
model.add(Dense(128, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(10, activation='softmax')) # 定义损失函数,一般来说分类问题的损失函数都选择采用交叉熵
# adagrad自适应的调整学习率的随机梯度下降算法 因为自适应所以会比较耗时间
model.compile(loss='categorical_crossentropy', optimizer='adagrad', metrics=['accuracy']) # 放入批量样本,进行训练
model.fit(X_train, y_train_ohe, validation_data=(X_test, y_test_ohe)#验证集作用边训练边测试 在每一个step中都会验证
, epochs=20, batch_size=128)
#epochs是迭代多少轮次 学完一轮是整个数据集/128 这里面有20轮 # 在测试集上评价模型的准确率
# verbose : 进度表示方式。0表示不显示数据,1表示显示进度条
scores = model.evaluate(X_test, y_test_ohe, verbose=0)#evaluate就是评估准确率
延伸结论:
最后一个卷积层到第一个全连接层的参数是最多的
结果:
【Keras篇】---Keras初始,两种模型构造方法,利用keras实现手写数字体识别的更多相关文章
- [机器学习] keras:MNIST手写数字体识别(DeepLearning 的 HelloWord程序)
深度学习界的Hello Word程序:MNIST手写数字体识别 learn from(仍然是李宏毅老师<机器学习>课程):http://speech.ee.ntu.edu.tw/~tlka ...
- 李宏毅 Keras手写数字集识别(优化篇)
在之前的一章中我们讲到的keras手写数字集的识别中,所使用的loss function为‘mse’,即均方差.那我们如何才能知道所得出的结果是不是overfitting?我们通过运行结果中的trai ...
- WebGL场景的两种地面构造方法
总述:大部分3D编程都涉及到地面元素,在场景中我们使用地面作为其他物体的承载基础,同时也用地面限制场景使用者的移动范围,还可以在通过设置地块的属性为场景的不同位置设置对应的计算规则.本文在WebGL平 ...
- Redis数据类型、两种模型、事务、内部命令
1.redis数据类型 a.字符串,使用场景:常规key-value缓存应用 set name lixiang get name append name 123 # 字符串追加 mset key va ...
- 【TensorFlow篇】--Tensorflow框架实现SoftMax模型识别手写数字集
一.前述 本文讲述用Tensorflow框架实现SoftMax模型识别手写数字集,来实现多分类. 同时对模型的保存和恢复做下示例. 二.具体原理 代码一:实现代码 #!/usr/bin/python ...
- Keras中间层输出的两种方式,即特征图可视化
训练好的模型,想要输入中间层的特征图,有两种方式: 1. 通过model.get_layer的方式.创建新的模型,输出为你要的层的名字. 创建模型,debug状态可以看到模型中,base_model/ ...
- fashion_mnist多分类训练,两种模型的保存与加载
from tensorflow.python.keras.preprocessing.image import load_img,img_to_array from tensorflow.python ...
- 死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- 异步编程的两种模型,闭包回调,和Lua的coroutine,到底哪一种消耗更大
今天和人讨论了一下CPS变形为闭包回调(典型为C#和JS),以及Lua这种具有真正堆栈,可以yield和resume的coroutine,两种以同步的形式写异步处理逻辑的解决方案的优缺点.之后生出疑问 ...
随机推荐
- eclipse工具的使用心得
一.eclipse工具的使用 eclipse是一个开源的IDE,进行javaEE开发一般使用myeclipse插件比较方便 1. java代码的位置 1)选择工作空间workspace 选择一个文件夹 ...
- selenium--unittest 框架/selenium--常见异常
selenium常见异常 from selenium import webdriver from selenium.webdriver.common.by import By from seleniu ...
- java某些基础知识点整理
1. \n换行 \r回车 \"双引号 \\反斜杠 2.Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. byte: byte 数据类型是 ...
- fileWriter.go
package blog4go import ( "fmt" "path" "strings" ) // NewFileWriter ini ...
- ConcurrentLinkedQueue简介
ConcurrentLinkedQueue是一个基于链表的无界线程安全队列,非阻塞实现方式,先进先出,适合高并发的场景. 非阻塞的性能较好,采用CAS,避免加锁的时间,保证数据一致性. 采用" ...
- mvc 三个 之间 肮脏的交易
就当个小零食一样写. MVC 是 Model-View-Controller 的缩写,Model代表的是应用的业务逻辑(通过 JavaBean,EJB 组件实现),View 是应用的表示层(由 JSP ...
- i春秋----Misc
好久没有写 博客今天更新多了一些 解题思路:题目做多了,自然能够想到是凯撒解密: 查看得到答案; flag{4c850c5b3b2756e67a91bad8e046dda} 2: 解题思路:是我想太多 ...
- 关于throw、throws、try--catch的问题
首先回顾概念 throws表示出现异常的一种可能性,并不一定会发生这些异常 throw则是抛出了异常,执行throw则一定抛出了某种异常 try--catch try语句用大括号{}指定了一段代码,该 ...
- js获取数组中最大值和最小值
var max = Math.max.apply(null, 数组); 获取最大值 var min = Math.min.apply(null, 数组);获取最小值 一句话获取数组中最大的数,最小数
- Go语言中的面向对象
前言 如果说最纯粹的面向对象语言,我觉得是Java无疑.而且Java语言的面向对象也是很直观,很容易理解的.class是基础,其他都是要写在class里的. 最近学习了Go语言,有了一些对比和思考.虽 ...