Tensorflow学习&深度学习实操(1)

本文最后更新于:2024年9月13日 早上

序言

其实高三的时候学习神经网络的时候就了解到有这么个东西了,当时是在知乎上看到了一位学长的文章入了神经网络的坑,跟着呢个学长的文章学习了许多,并且自己试着用c++实现了下简单的DNN和CNN,
这是当时码的,虽然十分简单但是拥有完整的正向反向传播梯度下降等
然后由于码量较大,只是做了两三个训练就废弃了。后来发现了有现成的库可以直接使用,不过当时找到的资料都是python+Tensorflow的组合,由于自己当时对PY不是太熟就没怎么学。最近一段时间学了些python的知识,并且数学建模需要神经网络来拟合,于是开一档记录Tensorflow的使用学习。

前置知识

matplotlib库

Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。 它也可以和图形工具包一起使用,如 PyQt 和 wxPython。

网络基础知识

虽然我们可以直接调用APi,但是对于网络原理还是需要必要的了解的。以及对一些名词要有理解
我个人是看这位华师的学长的文章,(就是高三的时候学的那些东西)

xlwings库

一个处理excal的库,比较方便
实例:

1
2
3
4
5
6
7
8
9
10
11
import xlwings as xw # 载入

output=open('a.out','w',1,'utf-8') #记录保存地址
wb = xw.Book('1.xlsx')# 打开excal文档
sht = wb.sheets[0] # 选择所需操作的sheet
for i in range(1,12) : # 取1到12列
Row=chr(i+ord('a')-1)
for j in range(1,3) :# 取1到3行
Range=str(j)
b = sht[Row+Range].value # sht[X]中X格式为‘字母+数字’,如‘B7’
print(b,file=output)

更多操作可以看知乎文章

Keras

引用一段Keras官网的话:

Keras 是一个用 Python 编写的高级神经网络 API,它能够以 TensorFlow, CNTK, 或者 Theano 作为后端运行。Keras 的开发重点是支持快速的实验。能够以最小的时延把你的想法转换为实验结果,是做好研究的关键。

Keras 的核心数据结构是 model,一种组织网络层的方式。最简单的模型是 Sequential 顺序模型,它是由多个网络层线性堆叠的模型形式。

载入Sequential模型

1
2
from keras.models import Sequential
model = Sequential()


添加网络层时可以直接使用add函数来叠加

1
2
3
from keras.layers import Dense
model.add(Dense(units=64, activation='relu', input_dim=100))
model.add(Dense(units=10, activation='softmax'))


使用compile 来配置学习过程

1
model.compile(loss='categorical_crossentropy',optimizer='sgd',metrics=['accuracy'])

参数:

optimizer: 优化器

optimizer的参数:
lr:大或等于0的浮点数,学习率
momentum:大或等于0的浮点数,动量参数
decay:大或等于0的浮点数,每次更新后的学习率衰减值
nesterov:布尔值,确定是否使用Nesterov动量

loss:损失函数,可以用自带的,也可以自定义.如果模型有多个输出,可以传入一个losslist,模型降会把这些损失加在一起
metrics: 评价函数,与损失函数类似,只不过评价函数的结果不会用于训练过程中,可以传递已有的评价函数名称,或者传递一个自定义的函数来使用

自带的评价函数有:binary_accuracy(y_true,y_pred), categorical_accuracy(y_true,y_pred),sparse_categorical_accuracy(y_true,y_pred), top_k_categorical_accuracy(y_true,y_pred,k=5).
自定义评价函数应该在编译的时候compile传递进去,该函数需要以(y_true,y_pred)作为输入参数,并返回一个张量作为输出结果.

loss_weights:可选项,是一个list或字典,指定不同的损失的权重

sample_weight_mode: 如果你需要执行按时间步采样权重(2D 权重),请将其设置为 temporal。 默认为 None,为采样权重(1D)。 如果模型有多个输出,则可以通过传递 mode 的字典或列表,以在每个输出上使用不同的 sample_weight_mode。
weighted_metrics: 在训练和测试期间,由 sample_weight 或 class_weight 评估和加权的度量标准列表。
target_tensors: 默认情况下,Keras 将为模型的目标创建一个占位符,在训练过程中将使用目标数据。 相反,如果你想使用自己的目标张量(反过来说,Keras 在训练期间不会载入这些目标张量的外部 Numpy 数据), 您可以通过 target_tensors 参数指定它们。 它可以是单个张量(单输出模型),张量列表,或一个映射输出名称到目标张量的字典。
kwargs: 当使用 Theano/CNTK 后端时,这些参数被传入 K.function。 当使用 TensorFlow 后端时,这些参数被传递到 tf.Session.run。

一些compile的参数学习


开始训练!
使用fit

1
2
# x_train 和 y_train 是 Numpy 数组
model.fitfit(x_train, y_train, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)

x_train: 训练数据的 Numpy 数组(如果模型只有一个输入), 或者是 Numpy 数组的列表(如果模型有多个输入)。 如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,x 可以是 None(默认)。
y_train: 目标(标签)数据的 Numpy 数组(如果模型只有一个输出), 或者是 Numpy 数组的列表(如果模型有多个输出)。 如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,y 可以是 None(默认)。
batch_size: 整数或 None。每次梯度更新的样本数。如果未指定,默认为 32。
epochs: 整数。训练模型迭代轮次。一个轮次是在整个 x 和 y 上的一轮迭代。 请注意,与 initial_epoch 一起,epochs 被理解为 「最终轮次」。模型并不是训练了 epochs 轮,而是到第 epochs 轮停止训练。
verbose: 0, 1 或 2。日志显示模式。 0 = 安静模式, 1 = 进度条, 2 = 每轮一行。
callbacks:一系列可以在训练时使用的回调函数。
validation_split: 0 和 1 之间的浮点数。用作验证集的训练数据的比例。 模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。 验证数据是混洗之前 x 和y 数据的最后一部分样本中。
validation_data: 元组 (x_val,y_val) 或元组 (x_val,y_val,val_sample_weights), 用来评估损失,以及在每轮结束时的任何模型度量指标。 模型将不会在这个数据上进行训练。这个参数会覆盖 validation_split。
shuffle:布尔值(是否在每轮迭代之前混洗数据)或者 字符串 (batch)。 batch 是处理 HDF5 数据限制的特殊选项,它对一个 batch 内部的数据进行混洗。 当 steps_per_epoch 非 None 时,这个参数无效。
class_weight: 可选的字典,用来映射类索引(整数)到权重(浮点)值,用于加权损失函数(仅在训练期间)。 这可能有助于告诉模型 「更多关注」来自代表性不足的类的样本。
sample_weight: 训练样本的可选 Numpy 权重数组,用于对损失函数进行加权(仅在训练期间)。 可以传递与输入样本长度相同的平坦(1D)Numpy 数组(权重和样本之间的 1:1 映射), 或者在时序数据的情况下,可以传递尺寸为 (samples, sequence_length) 的 2D 数组,以对每个样本的每个时间步施加不同的权重。 在这种情况下,应该确保在 compile() 中指定 sample_weight_mode=”temporal”。
initial_epoch: 整数。开始训练的轮次(有助于恢复之前的训练)。
steps_per_epoch: 整数或 None。 在声明一个轮次完成并开始下一个轮次之前的总步数(样品批次)。 使用 TensorFlow 数据张量等输入张量进行训练时,默认值 None 等于数据集中样本的数量除以 batch 的大小,如果无法确定,则为 1。
validation_steps: 只有在指定了 steps_per_epoch 时才有用。停止前要验证的总步数(批次样本)。

fit的返回是一个 History 对象。其 History.history 属性是连续 epoch 训练损失和评估值,以及验证集损失和评估值的记录(如果适用)
相关keras源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class History(Callback):
"""Callback that records events into a `History` object.
This callback is automatically applied to
every Keras model. The `History` object
gets returned by the `fit` method of models.
"""

def on_train_begin(self, logs=None):
self.epoch = []
self.history = {}

def on_epoch_end(self, epoch, logs=None):
logs = logs or {}
self.epoch.append(epoch)
for k, v in logs.items():
self.history.setdefault(k, []).append(v)

可以看出History类对象包含两个属性,分别为epoch和history


evaluate在测试模式下返回模型的误差值和评估标准值。计算是分批进行的。

1
evaluate(x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None)

x: 测试数据的 Numpy 数组(如果模型只有一个输入), 或者是 Numpy 数组的列表(如果模型有多个输入)。 如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到 Numpy 数组。
y: 目标(标签)数据的 Numpy 数组,或 Numpy 数组的列表(如果模型具有多个输出)。 如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到 Numpy 数组。
batch_size: 整数或 None。每次评估的样本数。如果未指定,默认为 32。
verbose: 0 或 1。日志显示模式。 0 = 安静模式,1 = 进度条。
sample_weight: 测试样本的可选 Numpy 权重数组,用于对损失函数进行加权。 可以传递与输入样本长度相同的扁平(1D)Numpy 数组(权重和样本之间的 1:1 映射), 或者在时序数据的情况下,传递尺寸为 (samples, sequence_length) 的 2D 数组,以对每个样本的每个时间步施加不同的权重。 在这种情况下,应该确保在 compile() 中指定 sample_weight_mode=”temporal”。
steps: 整数或 None。 声明评估结束之前的总步数(批次样本)。默认值 None。

返回值是一个标量测试误差(如果模型只有一个输出且没有评估标准) 或标量列表(如果模型具有多个输出 和/或 评估指标)。 属性 model.metrics_names 将提供标量输出的显示标签


样例

做江苏数学建模省赛时想用神经网络对数据集进行预测而码,结果不尽人意. ..再次记录,等修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.callbacks import ModelCheckpoint
import numpy as np

keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
#梯度下降优化器

output=open('a.out','w',1,'utf-8') #记录保存地址

ns=np.array([90.42, 5.616, 26.41, 4.216, 6.837, 28.18, 72.84, 31.58, 5.353, 25.83])
xs=np.array([[ 70849.02, 64717.58, 2016.886, 0, 0, 0, 0, 3000.0, 0, 0, 140583.486], [ 0, 0, 2431.162, 14798.85, 0, 0, 0, 0, 0, 0, 17230.012], [ 53042.87, 0, 0, 0, 32898.43, 3017.841, 0, 0, 4000.0, 0, 92959.141], [ 0, 0, 2016.886, 0, 0, 0, 20492.89, 0, 0, 0, 22509.776], [ 59332.56, 0, 0, 0, 49087.32, 0, 0, 2309.934, 3020.0, 0, 113749.814], [ 0, 0, 0, 24685.94, 0, 2318.845, 35198.66, 0, 3000.0, 0, 65203.445], [ 0, 0, 3015.853, 18908.83, 0, 0, 0, 0, 2000.0, 0, 23924.683], [ 63356.26, 58102.85, 1789.986, 0, 0, 0, 0, 0, 5000.0, 0, 128249.096], [ 0, 0, 0, 0, 0, 0, 0, 0, 29048.39, 4903.955, 33952.345], [ 77905.24, 71053.95, 2218.854, 0, 0, 0, 0, 0, 0, 4000.0, 155178.044], [ 53252.23, 0, 0, 1890.0, 0, 2482.972, 0, 0, 0, 0, 57625.202], [ 0, 0, 0, 0, 7470.0, 0, 64363.52, 4125.733, 0, 0, 75959.253], [ 73968.84, 67546.03, 2104.845, 0, 0, 0, 0, 0, 0, 0, 143619.715], [ 0, 0, 3110.85, 0, 52531.42, 0, 0, 0, 0, 0, 55642.27], [ 68946.43, 63056.18, 1963.863, 0, 0, 4000.0, 0, 300.0, 0, 0, 138266.473], [ 0, 0, 0, 0, 0, 0, 0, 0, 49153.19, 8314.933, 57468.123], [ 0, 0, 0, 0, 43314.34, 3523.842, 0, 3000.0, 0, 0, 49838.182], [ 0, 0, 0, 21715.9, 0, 2027.372, 31177.86, 0, 0, 0, 54921.132], [ 10000.0, 0, 3017.751, 0, 0, 0, 0, 0, 49073.83, 0, 62091.581], [ 0, 0, 3024.342, 0, 0, 0, 0, 0, 49381.45, 0, 52405.792]])
ys=np.array([ 24.17, 5.462, 30.913, 66.511, 26.944, 21.234, 5.42, 22.604, 6.719, 24.099, 77.765, 55.158, 24.035, 7.374, 24.136, 6.722, 8.286, 22.795, 9.12,5.869])


model=keras.Sequential()
model.add(Dense(20, input_dim=10, kernel_initializer='random_uniform', activation='relu'))
model.add(Dense(8, kernel_initializer='random_uniform', activation='relu'))
model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))
# Compile model

model.compile(loss='binary_crossentropy', optimizer = tf.keras.optimizers.SGD(lr = 0.1), metrics=['accuracy'])

#model.fit(xs,ys,epochs=5000,callbacks=[checkpoint])

xxs=[]
for i in range(0,19):
xxs.append([])
for j in range(0,10):
xxs[i].append(ns[j]*xs[i][j]/xs[i][10])
finx=np.array(xxs[i])
model.fit(finx,ys, validation_split=0.33, epochs=10, batch_size=1, callbacks=checkpoint, verbose=0)


model.summary() #打印神经网络结构,统计参数数目
#print(model.predict([10.0]),file=output)
#print(model.predict([20.0]),file=output)
output.close()