笔记:ML-LHY-8: “Hello world” of deep learning(digits detection)

这节课主要介绍使用keras实现一个数字(mnist)分类实验
SGD中batch_size(min-batch)的意义
pdf 视频

工具

由于TensorFlow和theano(微分库)使用起来比较灵活,上手没那么快,Kears是封装他们的一个库,可以实现常用的网络,而且Kears也已经作为TensorFlow的官方API,这里先使用Kears搭建网络

搭建第一个网络

这个实验是一个识别数字的网络
在这里插入图片描述
网络图:
在这里插入图片描述
还是按照之前提到的3个步骤:定义函数集(定义网络)、如何找好的函数(定义损失)、找最好的函数(梯度下降)

1定义函数集(定义网络)

在这里插入图片描述

def my_model():
    model = Sequential()
    # hidden layer 1
    model.add(Dense(input_dim=28 * 28, units=500))
    model.add(Activation('sigmoid'))
    # hidden layer 2
    model.add(Dense(units=500))
    model.add(Activation('sigmoid'))
    # output layer
    model.add(Dense(units=10))
    model.add(Activation('softmax'))
    return model
    
model = my_model()

2如何找好的函数(定义损失)

在这里插入图片描述
损失使用交叉熵,学习率优化使用adam算法

my_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

3找最好的函数(梯度下降)

在这里插入图片描述

工具不会已经在定义和配置了网络情况下就会梯度下降求最优,我们只要把数据丢进去,包括训练数据(特征x和标签y)

model.fit(x_train, y_train, batch_size=100, epochs=20)

注意还有batch_size大小说明:
batch_size就是每次处理的数目,比如数据集有50000笔,batch_size = 100每次处理随机选100笔example。1个epoch处理就会处理500个batch,更新500次参数

在这里插入图片描述

流程:

  • 随机初始化参数
  • 处理第一个batch(注意每笔是随机1、31…):
    L ′ = l 1 + l 31 + ⋯ L^{\prime}=l^{1}+l^{31}+\cdots L=l1+l31+
    更新参数
  • 处理第二个batch(注意每笔是随机2、16…):
    L ′ ′ = l 2 + l 16 + ⋯ L^{\prime \prime}=l^{2}+l^{16}+\cdots L=l2+l16+
    更新参数
  • 直到所有batch都被处理过,完成一个epoch

既然每个batch里面的example是随机的,就有可能batch之间有部分重叠,但是这里的随机选取可以防止陷入局部极值点

batch_size = 1时就是SGD(Stochastic Gradient Descent),因为每次选了一个example就更新参数。但是实际中在一个batch中可以使用GPU进行并行计算example,比如:
在这里插入图片描述
都是计算50000笔数据,batch_size = 10时要比batch_size = 1快10倍,事实上,如果GPU支持10个线程,那么并行处理10笔example的速度和单线程处理1笔example的速度是差不多的
batch_size = 10处理10个epoch需要170s时,更新参数次数也达到50000次,那么
在速度差不多的情况下,选择更稳定的batch_size = 10是优于batch_size = 1
需要注意的是:batch_size不能一直增加,达到线程最大数目时,也只能串行计算了。还有一个原因就是SGD的原因,如果batch_size = 10实际也是一种SGD,但是设置的太大的话,就会往total loss方向走陷入局部最小(用SGD就是防止进入局部最小)
在这里插入图片描述
如果用了GPU而没有设置batch_size的话,实际上是没有加速的

数据集下载和处理

用的是mnist数据

可以手动下载:具体看http://yann.lecun.com/exdb/mnist/
直接使用keras加载:

from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

也可使用keras提供的函数下载:具体看http://keras.io/datasets/

import tensorflow as tf
tf.keras.datasets.mnist.load_data(path="mnist.npz")
#  保存在 ~/.keras/datasets/mnist.npz

npz是numpy的文件存储,所以使用numpy加载:

path = "../DataSets/mnist.npz"
    with np.load(path, allow_pickle=True) as f:
        x_train, y_train = f['x_train'], f['y_train']
        x_test, y_test = f['x_test'], f['y_test']
    # 2维28 * 28转换成1维28 * 28:
	x_train = x_train.reshape(x_train.shape[0], 28 * 28)
   	x_test = x_test.reshape(x_test.shape[0], 28 * 28)

可以看到数据格式是28*28的灰度图,下图显示的是x
在这里插入图片描述

对应的y是5,神经网络最后输出的0~9的概率,因此需要把标签y转换成one hot编码,5对应的就是0000010000,使用np_utils.to_categorical:

	y_train = np_utils.to_categorical(y_train, 10)
	y_test = np_utils.to_categorical(y_test, 10)

测试还发现把像素值归一化到0~1可以提高准确度:

 	x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    x_train = x_train / 255
    x_test = x_test / 255

测试

result_train = model.evaluate(x_train, y_train)
result_test = model.evaluate(x_test, y_test)
print('Train Acc:', result_train[1])
print('Test Acc:', result_test[1])

代码

# from keras import datasets
# import tensorflow as tf
# tf.keras.datasets.mnist.load_data(path="mnist.npz")

import numpy as np
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.layers import Conv2D, MaxPooling2D, Flatten
from keras.optimizers import SGD, Adam
from keras.utils import np_utils
from keras.datasets import mnist
from keras.models import load_model

def load_data(): 
    path = "../DataSets/mnist.npz"
    with np.load(path, allow_pickle=True) as f:
        x_train, y_train = f['x_train'], f['y_train']
        x_test, y_test = f['x_test'], f['y_test']

    x_train = x_train.reshape(x_train.shape[0], 28 * 28)
    x_test = x_test.reshape(x_test.shape[0], 28 * 28)
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    x_train = x_train / 255
    x_test = x_test / 255

    y_train = np_utils.to_categorical(y_train, 10)
    y_test = np_utils.to_categorical(y_test, 10)
    
    return (x_train, y_train), (x_test, y_test)

def model():
    model = Sequential()
    # hidden layer 1
    model.add(Dense(input_dim=28 * 28, units=500))
    model.add(Activation('sigmoid'))

    # hidden layer 2
    model.add(Dense(units=500))
    model.add(Activation('sigmoid'))

    # output layer
    model.add(Dense(units=10))
    model.add(Activation('softmax'))
    return model

def train(model, path):
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    model.fit(x_train, y_train, batch_size=100, epochs=20)
    model.save(path)
    return model

if __name__ == '__main__':
	model_path = 'Model/m1.h5'
    is_train = True
    (x_train, y_train), (x_test, y_test) = load_data()
    
    if os.path.isfile(model_path) and is_train is False:
        model = load_model(model_path)
    else:
        model = model()
        train(model, model_path)

    result_train = model.evaluate(x_train, y_train)
    result_test = model.evaluate(x_test, y_test)
    print('Train Acc:', result_train[1])
    print('Test Acc:', result_test[1])

结果:

Train Acc: 0.995116651058197
Test Acc: 0.9768000245094299
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值