对于简单线性模型的机器学习
对于以下对应 x x x, y y y的值来预测当 x = 10 x = 10 x=10时 y y y的值
x | y |
---|---|
-1 | -3 |
0 | -1 |
1 | 1 |
2 | 3 |
3 | 5 |
4 | 7 |
通过找规律发现这是一个关于 y = 2 x − 1 y = 2x - 1 y=2x−1线性模型,那么对于机器而言如何让他做出对 x = 10 x = 10 x=10时 y y y值的判断呢?
代码如下:
from tensorflow import keras
import numpy as np
# 构建模型
model = keras.Sequential([keras.layers.Dense(units=1,input_shape=[1])])
model.compile(optimizer='sgd',loss='mean_squared_error')
# 准备训练数据,将x,y值存在浮点型数组里
x = np.array([-1.0,0.0,1.0,2.0,3.0,4.0], dtype=float)
y = np.array([-3.0,-1.0,1.0,3.0,5.0,7.0], dtype=float)
# 训练模型
model.fit(x,y,epochs=500)
# 使用模型
print(model.predict([10.0]))
- 这里我们调用TensorFlow中的Keras库。使用Keras中的Sequential (序贯模型),序贯模型是函数式模型的简略版,为最简单的线性、从头到尾的结构顺序,不分叉,是多个网络层的线性堆叠。Sequential 需要接收一个表示尺寸的元组给第一层模型。
- keras.layers.Dense()是全连接层函数。这里units=1代表是一维的,input_shape=[1]代表输入一个 x x x值。
- model.compile(optimizer=‘sgd’,loss=‘mean_squared_error’)定义模型并指定随机梯度下降(sgd)优化算法和均值误差(mean_squared_error)损失函数的情况,用于回归类型问题。
- model.fit()将训练数据在模型中训练一定次数,返回loss和测量指标
运行结果:
由此可见,随着训练次数的增加损失函数loss的值在不断变小,说明训练是有效的。
最后的预测结果为18.98758,可见跟正确答案19是非常接近的。
对简单像素图片的学习
这里我们的训练数据采用Keras数据库中的Fashion-MNIST数据集。
Fashion-MNIST总共有十个类别的图像。每一个类别由训练数据集6000张图像和测试数据集1000张图像。所以训练集和测试集分别包含60000张和10000张。每一个输入图像的高度和宽度均为28像素。如图:
代码如下:
import tensorflow as tf
from tensorflow import keras
#加载数据集 text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat', 'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
fashion_mnist = keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels) = fashion_mnist.load_data()
#构建模型
model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28,28))) #输入层
model.add(keras.layers.Dense(128,activation=tf.nn.relu)) #中间层
model.add(keras.layers.Dense(10,activation=tf.nn.softmax)) #输出层
#训练模型
train_images_scaled = train_images/255 #变成0-1之间的数效果会更好
model.compile(optimizer=tf.optimizers.Adam(),loss=tf.losses.sparse_categorical_crossentropy,metrics=['accuracy'])
model.fit(train_images_scaled,train_labels,epochs=5)
#测试模型
test_images_scaled = test_images/255
model.evaluate(test_images_scaled,test_labels)
#预测单张图片
import numpy as np
import matplotlib.pyplot as plt
print(np.argmax(model.predict([[(test_images[0]/255).reshape(1,28,28)]])))
print(test_labels[0])
其中构建了一个三层结构的模型如下:
-
第一层中keras.layers.Flatten()用于将输入层的数据压成一维的数据.
-
第二层运用了激活函数ReLU。ReLU函数是一种通用的激活函数,根据经验,您可以从使用ReLU函数开始,然后在ReLU不能提供最佳结果的情况下转移到其他激活函数。
-
第三层运用了Softmax函数作为激活函数。softmax函数可用于多类分类问题。这个函数返回属于每个类的数据点的概率。
运行结果:
可见该模型loss逐渐减少,accuracy逐渐增加。最后预测单张图片预测结果是9号标签,预测成功。
构建简单的卷积神经网络
上述方法我们构建的是全连接层,在此基础上我们来构建卷积层。
一维卷积
其中一维卷积常用在序列模型、自然语言处理领域;
假设输入数据维度为8,filter维度为5;不加padding时,输出维度为4,如果filter的数量为16,那么输出数据的shape就是
4
×
16
4\times16
4×16;
二维卷积
二维卷积常用在计算机视觉、图像处理领域(在视频的处理中,是对每一帧图像分别利用CNN来进行识别,没有考虑时间维度的信息);
假设原始图像 shape 为 14 × 14 × 3 14\times14\times3 14×14×3(其中3为3个通道),使用32个大小为 5 × 5 × 3 5\times5\times3 5×5×3(其中3为深度,与通道数相同)的卷积核对其进行卷积,得到特征图的shape为 10 × 10 × 32 10\times10\times32 10×10×32;
三维卷积
三维卷积就是在神经网络的输入中增加时间这个维度(连续帧),神经网络就可以同时提取时间和空间特征,进行行为识别、视频处理;
上图的三维卷积是对连续的三帧图像进行卷积操作(堆叠多个连续帧组成一个立方体,在立方体中利用三维卷积核进行卷积,这样得到的每个特征map都与上一层中3个邻近的连续帧相连);
因此我们采用的是二维卷积
代码如下:
import tensorflow as tf
from tensorflow import keras
#加载数据集 text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat', 'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
fashion_mnist = keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels) = fashion_mnist.load_data()
#构建卷积神经网络模型
model = keras.Sequential()
#构建卷积层
model.add(keras.layers.Conv2D(64,(3,3),activation='relu',input_shape=(28,28,1))) #构建二维卷积层进行过滤
model.add(keras.layers.MaxPooling2D(2,2)) #进行特征加强
model.add(keras.layers.Conv2D(64,(3,3),activation='relu')) #重复提高效果,但重复多容易过拟合
model.add(keras.layers.MaxPooling2D(2,2))
model.add(keras.layers.Flatten()) #输入层
model.add(keras.layers.Dense(128,activation=tf.nn.relu)) #中间层
model.add(keras.layers.Dense(10,activation=tf.nn.softmax)) #输出层
#训练模型
train_images_scaled = train_images/255
model.compile(optimizer=tf.optimizers.Adam(),loss=tf.losses.sparse_categorical_crossentropy,metrics=['accuracy'])
model.fit(train_images_scaled.reshape(-1,28,28,1),train_labels,epochs=5)
- Conv2D(64,(3,3),activation=‘relu’,input_shape=(28,28,1))表示在二维卷积中构建64个 3 × 3 3\times3 3×3的过滤器,采用Relu激活函数,输入为 28 × 28 28\times28 28×28像素、灰度为1的图片。
- max pooling 的目标是把卷积操作得到的结果进一步“挤压”出更有用的信息,有点类似于用力拧毛巾,把不必要的水分给挤兑掉。max pooling 其实是把一个二维矩阵取最大值进行2*2的分块,这部分跟前面描述的卷积很像,具体操作如下图:
- 之后的重复虽然shape没有改变,但参数是不一样的,不一样的参数意味着在提取不同的特征。这样能够提取更抽象、更本质的特征。虽然重复卷积可以提取出高级的特征,但卷积的深度并不是越多越好,要和训练集匹配以避免过拟合。
- train_images_scaled.reshape(-1,28,28,1) 如果等于-1的话,那么Numpy会根据剩下的维度计算出数组的另外一个shape属性值。
运行结果:
可见在采用卷积神经网络后精度有所上升,但是运行时间会大为增加。
各层结构如下:
- 第一行中用64个 3 × 3 3\times3 3×3的过滤器去处理 28 × 28 28\times28 28×28像素图片,所以 28-3+1=26个像素。参数个位 ( 3 ∗ 3 + 1 ) ∗ 64 (3*3+1)*64 (3∗3+1)∗64,其中+1是自动添加的一个blas。
- 第二行加强特征将行列数各减半所以变成 ( 13 , 13 , 64 ) (13,13,64) (13,13,64)