工作生活

简单的demo来了解deep learning

2019-07-14  本文已影响0人  滴滴水不断

mnist data

简介

MNIST 数据集来自美国国家标准与技术研究所。


mnist例子
使用:
>>> import tensorflow as tf
>>> (train_x, train_label), (test_x, test_label) = tf.keras.datasets.mnist.load_data()
>>> print(train_x.shape, train_label.shape, test_x.shape, test_label.shape)
(60000, 28, 28) (60000,) (10000, 28, 28) (10000,)

使用keras来train mnist data

keras

Keras是一个由Python编写的开源人工神经网络库,是对一些深度学习框架的(Tensorflow或Microsoft-CNTK或Theano等作为后端)再次封装:

  1. Keras 为支持快速实验而生,能够把你的idea迅速转换为结果
  2. 速度上慢
  3. 默认是以tensorflow为后端,可以更改为其他的。
最简单的实现: y=ax+b
# build a model
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28, 28)))
model.add(tf.keras.layers.Dense(10, activation=tf.nn.softmax))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# prepare data
mnist = tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train = tf.keras.utils.normalize(x_train, axis=1)
x_test = tf.keras.utils.normalize(x_test, axis=1)

# train
model.fit(x_train, y_train, epochs=1)

# evaluate
val_loss, val_acc = model.evaluate(x_test, y_test)
print("loss:{}".format(val_loss))
print("accuracy:{}".format(val_acc))

---->为实验而生

numpy实现train mnist data来理解上述代码

简单的公式开始

y=a*x+b
1.x是输入的一副图片:28 * 28
2.a是参数矩阵,我们改为W,单词weight
3.b也是参数,单词bias
4.y是预测结果
5.W为什么是10列?分类预测,类别数
6.softmax

简单的全连接层
目的

得到参数矩阵W和b,从而给定新的一副图片x,能得到预测的数字y

方法

对于公式y=xW + b
通过大量的已有数据和标签对,学习得到参数W和b
学校时,我们通过已知的点求未知数W,b;但是W和b太多太多,几千万,上亿参数,机器学习使用如下方法:
1.随机数初始化W和b。此时对于x输入,得到的y肯定是不准的
2.不准,不准有多离谱----》量化----》损失函数:当前参数W和b所算出来的y和正确的y的差距
3.loss(W[i, j]) = sum(xW+b - label),对于我们大量的x和label,找到W和b使得loss最小,就是机器学习。---从数据学习到特征(W和b)
4.从而变成,求函数Loss的最小值问题。
5.从而变成计算机来求函数最小值问题-----梯度下降法等

梯度下降法

梯度:
1.函数斜率---》函数变化最快的方向(山最陡峭的方向)---》沿着这个方向变化能减少函数值
2.沿着这个方向变化多少---》学习率
3.找山谷,高度z是x,y的函数,从最高点往最低点走的过程就是训练一个模型;每走的一步,都是往当前最陡峭的方向走,这样就能往低处走,每一步有x,y2个方向;而损失函数是W,b的函数,W和b是矩阵,是有很多个元素(成千上万),它的每一步,就有很多方向都要调节。
W[i,j] = W[i, j] - learn_rate * V

代码实现

1.W, b初始化

self._W = np.random.rand(784, 10)
self._b = np.random.rand(10)

输出10的理解
2.预测函数

    def predict(self, x):
        y = np.dot(x, self._W) + self._b
        return softmax(y)

softmax的理解:https://www.jianshu.com/p/699d18a2e642
3.损失函数

    def loss(self, x, t):
        y = self.predict(x)
        return cross_entropy_error(t, y)

corss entropy的理解:https://www.jianshu.com/p/3e44423eedcf
4.学习过程(训练)

    def train(self, iteration_count, batch_size = 100, lr=0.1):
        for it in range(iteration_count):
            print("train iteration:{}".format(it))
            train_data, train_label = self._mnist_data.get_random_train_data(batch_size)
            grad_W, grad_b = self.gradient(train_data, train_label)
            self.update_parameter(self._W, grad_W, lr)
            self.update_parameter(self._b, grad_b, lr)
        print("train done")

5.每一步调整参数

@staticmethod
    def update_parameter(param, grad, lr):
        it = np.nditer(param, flags=['multi_index'], op_flags=['readwrite'])
        while not it.finished:
            i = it.multi_index
            param[i] -=  lr*grad[i]

            it.iternext()

6.梯度下降法

def gradient(self, train_data, train_label):
    loss_func = lambda W: self.loss(train_data, train_label)
    grad_W = gradient(loss_func, self._W)
    grad_b = gradient(loss_func, self._b)
    return grad_W, grad_b

def gradient(loss_fun, W):
    delta = 0.01
    grad = np.zeros_like(W)
    it = np.nditer(W, flags=['multi_index'], op_flags=['readwrite'])
    while not it.finished:
        idx = it.multi_index
        tmp = W[idx]
        W[idx] = tmp + delta
        f1 = loss_fun(W)

        W[idx] = tmp - delta
        f2 = loss_fun(W)

        grad[idx] = (f1 - f2) / (2*delta)
        W[idx] = tmp

        it.iternext()
    return grad

出现的问题

图片被转成1维(降维打击),丢失空间信息

CNN

Keras代码很少,但是背后做了很多事情
理解了数据流程图,就能理解代码

总的数据流程图
2个Convolution层
全连接和输出层
过滤器or卷积核

1.一个小矩阵,代表即将学到的一个特征,和输入的某一片作用,从而让空间信息起了作用(比如初期的边沿特征,后面高级的特征,鼻子等)


Convolution
2个通道输入的图片

2.卷积的步幅
3.Padding,边沿补充0

池化Pool
Pool

作用:
1.缩小输入
2.缓解卷积对位置的过度敏感性
方式:
1.最大值
2.均值池化

激励函数
作用
  1. x经过多个xW+b后,其实可以用一个W和b代替,这样相当于起作用的权重和偏置参数有限。
  2. 经过了激励函数后,各个W和b都可以起作用,相当于最后的输出有更多的控制量了(模型空间),从而学习或者训练,可以无止境了。
常用激励函数

1.ReLu
公式:y=max(x, 0)
图形:


image.png

2.Sigmoid
公式:y=1/(1+exp(-x))
图形:


image.png

用Keras实现CNN识别

代码:
    model = keras.models.Sequential()

    # first convolution layer
    model.add(keras.layers.Convolution2D(filters=32, kernel_size=(5, 5), strides=(1, 1), activation='relu'))
    model.add(keras.layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2)))

    # second convolution layer
    model.add(keras.layers.Convolution2D(filters=64, kernel_size=(5, 5), strides=(1, 1), activation='relu'))
    model.add(keras.layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2)))

    # full connect
    model.add(keras.layers.Flatten())
    model.add(keras.layers.Dense(1024, activation='relu'))

    # softmax
    model.add(keras.layers.Dense(10, activation='softmax'))

    model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(lr=0.01), metrics=['accuracy'])

    (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
    x_train = x_train.reshape(-1, 28, 28, 1).astype('float32')/255
    y_train = keras.utils.to_categorical(y_train, 10)

    x_test = x_test.reshape(-1, 28, 28, 1).astype('float32')/255
    y_test = keras.utils.to_categorical(y_test, 10)

    model.fit(x_train, y_train, batch_size=100, epochs=1, validation_data=(x_test, y_test))

基于CNN的经典模型

Lenet,1986年
Alexnet,2012年
GoogleNet,2014年
VGG,2014年
Deep Residual Learning,2015年

参考

<<深度学习入门:基于Python的理论与实现>>
<<动手学深度学习>>
图解CNN
人类视觉原理和CNN
CNN的经典模型

上一篇 下一篇

猜你喜欢

热点阅读