机器学习简介
文章目录
机器学习简介
知识点
- 理解机器学习
- 以人类学习认识石头剪刀布为例,一个小孩子在初次接触这个时会有人告诉他:“偶这个就是石头哦!”,不过他看到你给他做的实例是:“手握起来 背面向下 手是黑色的”,于是他学会了这个就是石头。后来他看见“手握起来 背面向上”也有人说是石头,于是他就知道了“手握起来 背面向下或者向下 手是黑色的”就是石头,再到后来他还发现只要是手握住拳头就是石头,不管是朝着哪个方向,不管手是什么颜色。
- 机器学习就是模拟这种学习方式的,也就是你告诉计算机输入以及结果,计算机需要自己尝试去构建出其中的规律。
- 理解机器学习中一定存在的不确定性
- 机器创建出来的规则总规是“猜出来的”,比较输入的数据并并不是完全的原始数据。
- 建立一个神经网络步骤
- 导入模块
- 明确数据
- 构架模型
- 配置模型
- 训练模型
- 使用模型
代码
具体的模型构建、配置、训练请看下一节
from tensorflow import keras
import numpy as np
model = keras.models.Sequential([
keras.layers.Dense(units=10, input_shape=[1]),
keras.layers.Dense(units=1, input_shape=[1]),
])
model.compile(optimizer='sgd',
loss='mean_squared_error')
x = np.array([-1, 0, 1, 2, 3, 4, 5, 6, 7], dtype=float)
y = x * 2 + 1 # 当这里是线性的时候数据非常准确
model.fit(x, y, epochs=500)
predict = model.predict([1.2])
print(predict)
机器学习中基本计算机视觉概念
知识点
- 构建tensorflow自带的数据集:fashion_mnist的神经网络
代码
认识数据集
- fashion_mnist数据集有6000张28*28的单通道图像
- 打印出第一张图片就是这样:
- 这张图片由一个28*28的二维矩阵表示
- 在这里我将其归一化了,且注意数据是float
- 特别需要提醒的是,数据类型一定要匹配,矩阵维度也要匹配
import tensorflow as tf
from tensorflow.keras.datasets import fashion_mnist
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
print(tf.__version__)
(training_imags, training_labels), (testing_imags, testing_labels) = fashion_mnist.load_data()
plt.imshow(training_imags[0])
plt.show()
print(training_labels[0])
print(training_imags[0])
training_imags = training_imags / 255.
testing_imags = testing_imags / 255.
创建并配置模型
- 创建模型,一共是三层
- Flatten层:图片数据被输入后,我们需要用一个28*28的矩阵来处理(也就是我们需要用相同维度的神经元来处理它),也许这个想法不错,但是还可以将这个二维的图像矩阵转为一维的矩阵即:1 * 784 (28 * 28 = 784)来进行处理,那么我们就只需要一层神经元就可以达到目的了。所以你可以考虑将这个数据集中的每一张图片手动转化为一维的数据,但是好消息是模型Flatten层能帮你做这件事,显然,他不需要参数就可以。
- Dense层:也就是我们的神经元,units是神经元个数,activation是激活函数(与其说是激活倒不如说是变形函数,理解为:他将不同位置的数据值投影到不同的值上去,比如说relu函数,当数值小于0的时候就投影到0,当数值大于0的时候就投影到该数值大小)
- 当然,如果你愿意或者说你计算机愿意计算的话,你也可以添加更多层网络,毕竟Sequential里面是一个列表,不出意外的话你可以添加无限层。不过层数越多就越好吗?那不一定!
- 配置模型
- optimizer:在你学习数学的时候,不同的老师教学的方法不同,神经网络在不学习的过程中,不同的优化器就扮演这种角色。显然没有最好的优化器,只有最合适的优化器。
- loss:每次数学考试之后总会有一个数字叫做“成绩”来告诉你的优劣程度,如果比较低,那么你得到的结果及时我需要再努力一点,如果达到预期的高度了,那么我可以选择稳住。神经网络中以loss函数函数值来量化输出结果与真实结果的差距,以此更新,并让自己活得更好。
- metrics:指标的意思,写上就好了。
- 训练模型
- 分别输入数据集的特征、标签
- 循环5次
- 每一次喂入32个数据
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy']
)
model.fit(training_imags, training_labels, epochs=5, batch_size=32)
使用数据
-
检测数据
-
将测试数据集输入并查看loss值和准确率
-
testing_loss, testing_accuracy = model.evaluate(testing_imags, testing_labels) print("Testing Loss: {} \t Tesing Accuracy: {}".format(testing_loss, testing_accuracy))
-
-
用数据预测
-
注意predict_testing_0是第一组测试数据,有10个数据,每一个数据分别表示这个样本属于某一个标签的概率
-
predict_testing = model.predict(testing_imags) predict_tesitng_0 = predict_testing[0] testing_labels_0 = testing_labels[0] print("Predict : {} \n Labels : {}".format(predict_tesitng_0, testing_labels_0))
-
-
手动计算准确率
-
predict_labels = tf.argmax(input=predict_testing, axis=1) predict_labels = tf.cast(predict_labels, tf.int64) predict_labels = np.array(predict_labels) df = pd.DataFrame() df[0] = testing_labels df[1] = predict_labels print("Accuracy : {}".format(np.sum(df[0] == df[1]) / df.shape[0]))
-
一些知识点
- It’s the probability that this item is each of the 10 classes
- 如果增加了Dense的Units:Training takes longer, but is more accurate
- 考虑将Flatten层去掉:会报错,因为:我们希望网络输入数据的形状和神经元组成是相同的,TensorFlow 2 中用Flatten将28*28的拉成784*的
- 考虑将最后一层的数量改为5 or 15:会报错,The number of neurons in the last layer should match the number of classes you are
classifying for. - 考虑增加更多的Dense层:对此数据集没必要,但是当数据集中特征很多的时候便可能可以得到较好的特征提取
- 考虑循环多次:可能会出现过拟合,损失函数不降反增
- 考虑不将像素点数据归一化:准确率会下降
- 为什么要归一化? 去除量纲的影响?
- 尝试使用回调函数
卷积神经网络简介
知识点
- 先对图像特征进行提取,再送入到神经网络中,使得特征更加凸显
- 通过不同的卷积核进行卷积可以提取图像不同的特征
- 通过不同的池化提取图片的特征数据集成在一个数据上,最后图片可以变小且特征还保留
- TF中,图片经过卷积神经网络提取特征数据(特征提取)后传入神经网络
- 网络能通过图像特征而不只是像素进行学习
代码
import tensorflow as tf
from tensorflow.keras.datasets import fashion_mnist
import matplotlib.pyplot as plt
import numpy as np
(training_imags, training_labels), (testing_imags, testing_labels) = fashion_mnist.load_data()
training_imags = np.reshape(training_imags, (training_labels.shape[0], 28, 28, 1))
testing_imags = np.reshape(testing_imags, (testing_labels.shape[0], 28, 28, 1))
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(28, 28, 1)),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(28, 28, 1)),
tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(
optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy']
)
model.fit(training_imags, training_labels, epochs=5)
loss_test, accuracy_test = model.evaluate(testing_imags, testing_labels)
print("Loss of test : {} \t Accuracy of test : {}".format(loss_test, accuracy_test))
思考
- 考虑添加卷积网络后的变换?
- 优点
- 不单单只是用像素点的值来学习,还包含图片的特征,从而使学习效果会更好
- 缺点
- 计算变慢很多
- 优点
- 为什么要将图片数据维度变为
(28, 28, 1)
- 图片是一张一张喂入到卷积层的,而数据集的维度是
(60000, 28, 28)
- 如何表示一张图片呢?用单通道:
(width, height, channels=1)
- 所以我们将数据集
reshape(60000, 28, 28, 1)
- 图片是一张一张喂入到卷积层的,而数据集的维度是