前言
仅记录学习过程,有问题欢迎讨论
什么是神经网络:
- 神经网络是一种模拟人脑神经元工作原理的算法,它由多个神经元组成,每个神经元都接受输入,通过计算产生输出,并将输出传递给其他神经元。
- 神经网络的基本结构包括输入层、隐藏层和输出层。输入层接受外部输入,隐藏层对输入进行计算和转换,输出层产生最终的输出。神经网络中的神经元之间通过权重连接,权重决定了神经元之间的连接强度。
- 神经网络的学习过程是通过调整权重来实现的。在训练过程中,神经网络会根据输入数据和期望输出,计算误差,并使用梯度下降等优化算法来调整权重,以减少误差。经过多次迭代,学习到输入数据和输出数据之间的关系,从而实现分类、回归等任务
激活函数:引入了非线性的学习和处理的能力
swish:
-
在x为负值时,Swish函数输出的负值小于x本身,但不为0,这使得神经元保持一定的激活程度
-
在零点附近平滑过渡,没有明确的分界点,这有助于梯度的稳定传播
监督学习(有标注样本):
- 标准的神经网络(Neural Networt):预测房屋价格;是否点击广告
- 卷积神经网络(Convolutional NN):图像识别;
- 循环神经网络(Recurrent NN,序列时间线的数据):音频识别;语言翻译
- 混合神经网络:雷达;无人驾驶
无监督学习:
- 给予机器没有标注的信息,希望通过算法进行一定的分析,得到一些结论
- 常见任务:聚类、降维、找特征值
分布外数据(Out - of - Distribution,OOD):
原因:
- 数据收集偏差:如果在数据收集过程中只关注了特定类型的数据,那么其他类型的数据就会成为 OOD 数据。例如,在收集图像数据时,如果只收集了室内场景的图片,那么室外场景的图片对于这个模型来说就是 OOD 数据。
- 数据生成过程变化:当数据的生成机制发生变化时,也会产生 OOD 数据。例如,在时间序列数据中,经济环境的变化可能导致数据生成过程与之前不同,新的数据就可能是 OOD 数据
解决:
-
OOD 检测(Out - of - Distribution Detection):开发专门的方法来检测数据是否属于 OOD。例如,使用基于
密度估计(概率分布)、距离度量(K-means)或分类器的方法来判断数据是否超出了训练数据的分布范围。 -
模型适应(Model Adaptation):当发现 OOD 数据时,尝试对模型进行调整或重新训练,使其能够适应新的数据分布。例如,采用迁移学习或增量学习的方法,将已有模型的知识迁移到新的数据分布上,或者在新数据上逐步更新模型
前向和反向传播
通过前向传播,模型可以根据输入数据生成预测结果(forward),获取损失函数;
通过反向传播,可以计算模型的梯度信息(loss),从而进行参数优化。
- 沿着正向传播的路线反向走!反向传播过程中利用下一层存储的值以及梯度的分向量来更新上一层的w和b,极大的提高了梯度计算速度,从而更加有利于利用梯度进行随机梯度下降更新神经网络参数完成机器学习训练任务
- 先随机权重,计算loss,然后反向传播更新权重(通过就偏导知道该w对loss的影响,得出增大or缩小改w)
计算梯度的方法:
- 随机梯度下降:代表随机抽样部分数据代替整体(随机一个批次),减少计算量,通过不断沿着反梯度方向(向量拆分)更新参数求解。学习率代表下降的步子,批量随机梯度下降是默认求解方法.
- 缺点:收敛局部最小值;参数调整比较缓慢
- 牛顿法:(求导求极值,求出所有找最优,计算量大)优化下降路径
- 冲(动)量法:通过历史数据来修正每一次的梯度分量(有惯性),越远的影响越小,加权,减少震荡
- AdaGrad:学习率自适应改动,历史数据的学习率加权,速度比不过冲量法
- Adam:AdaGrad+动量法!
过拟合:
对于测试集的效果差,泛化能力差;可能训练数据带有噪音,或者参数过多导致模型复杂度高
解决办法:减少特征,清洗数据,更多训练样本,dropout,正则化
训练过程:
先随机权重,计算loss,然后反向传播更新权重(通过求偏导知道该w对loss的影响,得出增大or缩小改w)
Keras:
Keras是由纯python编写的基于theano/tensorflow的深度学习框架。
Keras是一个高层神经网络API,支持
a)简易和快速的原型设计(keras具有高度模块化,极简,和可扩充特性)
b)支持CNN和RNN,或二者的结合
c)无缝CPU和GPU切换
手动实现一个神经网络
"""
work-从零训练一个简单的 识别图片数字的模型
"""
import numpy
# 加载数据 返回图片数组和对应label数组
def load_data_set(file_name):
label = []
img_data = []
# 加载图片csv
data_file = open(file_name)
data_list = data_file.readlines()
data_file.close()
# data_list[0]是第一张图片,data_list[0].split(',')是按照','分割的字符串
for data in data_list:
# 第一个值对应的是图片的表示的数字,所以我们读取图片数据时要去掉第一个数值
all_values = data.split(',')
image_array = numpy.asfarray(all_values[1:]).reshape((28, 28))
img_data.append(image_array)
label.append(all_values[0])
return img_data, label
# 建立模型结构
class NeuralNetWork:
def __init__(self,input_nodes, hidden_nodes, output_nodes,lr):
self.input_nodes = input_nodes
self.hidden_nodes = hidden_nodes
self.output_nodes = output_nodes
self.lr = lr
# 初始化权重
self.wih = numpy.random.normal(0.0, pow(self.hidden_nodes, -0.5), (self.hidden_nodes, self.input_nodes))
self.who = numpy.random.normal(0.0, pow(self.output_nodes, -0.5), (self.output_nodes, self.hidden_nodes))
# 定义sigmoid 激活函数
self.activation_function = lambda x: 1 / (1 + numpy.exp(-x))
def train(self, inputs_list, targets_list):
# 数据需要转换为 二维数组
inputs = numpy.array(inputs_list, ndmin=2).T
targets = numpy.array(targets_list, ndmin=2).T
# 前向传播
hidden_inputs = numpy.dot(self.wih, inputs)
hidden_outputs = self.activation_function(hidden_inputs)
final_inputs = numpy.dot(self.who, hidden_outputs)
final_outputs = self.activation_function(final_inputs)
# 反向传播
# 计算loss
output_loss = targets - final_outputs
hidden_errors = numpy.dot(self.who.T, output_loss * final_outputs * (1 - final_outputs))
self.who += self.lr * numpy.dot((output_loss * final_outputs * (1.0 - final_outputs)), numpy.transpose(hidden_outputs))
self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), numpy.transpose(inputs))
# 预测
def query(self, inputs_list):
inputs = numpy.array(inputs_list, ndmin=2).T
hidden_inputs = numpy.dot(self.wih, inputs)
hidden_outputs = self.activation_function(hidden_inputs)
final_inputs = numpy.dot(self.who, hidden_outputs)
final_outputs = self.activation_function(final_inputs)
return final_outputs
# 测试模型效果
def predict(network):
print("开始预测")
img_data, true_label = load_data_set("dataset/mnist_test.csv")
scores = []
for i in range(len(img_data)):
inputs = img_data[i]
# 将图像数据从0-255的整数范围归一化到0.02-1.00的浮点数范围,以便更好地用于机器学习模型的训练和预测。、
# 归一化处理可以加快模型的收敛速度,提高模型的性能
inputs = (numpy.asfarray(inputs.reshape(-1))) / 255.0 * 0.99 + 0.01
# 初始化one-hot
targets = [0.01] * 10
targets[int(true_label[i])] = 0.99
outputs = network.query(inputs)
# 找到数值最大的神经元对应的 编号
label = numpy.argmax(outputs)
print("predict is : ", label)
print("true is : ", true_label[i])
# print("网络认为图片的数字是:", label)
if label == int(true_label[i]):
scores.append(1)
else:
scores.append(0)
# 计算图片判断的成功率
scores_array = numpy.asarray(scores)
print("perfermance = ", scores_array.sum() / scores_array.size)
def main():
img_data, label = load_data_set("dataset/mnist_train.csv")
# 定义超参数
input_nodes = 784
hidden_nodes = 200
output_nodes = 10
learning_rate = 0.01
epochs = 5
# 建立模型
network = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)
for epoch in range(epochs):
for i in range(len(img_data)):
inputs = img_data[i]
# 将图像数据从0-255的整数范围归一化到0.02-1.00的浮点数范围,以便更好地用于机器学习模型的训练和预测。、
# 归一化处理可以加快模型的收敛速度,提高模型的性能
inputs = (numpy.asfarray(inputs.reshape(-1))) / 255.0 * 0.99 + 0.01
# 初始化one-hot
targets = [0.01] * 10
targets[int(label[i])] = 0.99
network.train(inputs, targets)
print("训练完成")
predict(network)
if __name__ == '__main__':
main()