keras 将散点数据拟合为函数
# 导⼊相应的库包
import tensorflow as tf
import numpy as np
import tensorflow.keras as keras
import matplotlib.pyplot as plt
# 构造⼈造数据
X = np.linspace(-1, 1, 200) #在[-1,1]之间⽣成200个数作为x
# 将x乘以2+1,再加上⼀个[-1,1]区间的随机数*0.4作为加⼊的噪声
np.random.seed(5) # 设置随机数种⼦
# y=2x + 1 + 噪声 其中噪声的维度和x_data⼀致
Y = 2.0 * X + 1.0 + np.random.randn(*X.shape) * 0.4
# 定义模型:
model = keras.Sequential()
# 构建Dense()层,构建y=wx+b关系
layer_1 = keras.layers.Dense(1,input_shape=(1,)) # Dense(输出数据维度,输⼊数据维度)
model.add(layer_1) # 为模型添加Dense()层
info = model.summary()
print(info)# 查看当前模型信息
# 模型编译:
# 为指定模型训练⽤的优化算法和损失函数
# 优化算法:sgd(随机梯度下降法),损失函数:mean square error
model.compile(optimizer="sgd",loss="mse")
# 将数据分为训练集和测试数据集
X_train, Y_train = X[:160], Y[:160] # 前160组数据为训练数据集
X_test, Y_test = X[160:], Y[160:] # 后40组数据为测试数据集
# 模型训练
# ⽤fit开始训练,训练次数epochs=100,注意训练模型的函数有多个,具体查看前⾯的PPT
model.fit(x=X_train,y=Y_train,epochs=100)
# 显示训练后的参数
W, b = model.layers[0].get_weights()
##注意这里的get_weights
这个算法仍然是把y作为特征值,每个点的x都是数据
数据到特征值的算法会自动计算出权重w和参数b
对于任何算法都是有的
恰好本题需要斜率w和截距b
get_weights就已经获得了
并不是通过编译使得特征值为w和b
,而且layers[0]表示表层的一个,其实一共也就一层,问题在于为什么这么多点只用一层
实际上,输入的层数(维度) 是看每一个变量的纬度,而不是多少行变量,
手写体的60000行,也只输入(28, 28, 1)
print('Weights=', W, '\nbiases=', b)
# 查看构造的数据
plt.scatter(X,Y,color='r')
# 画出想通过学习得到的⽬标线性函数y=2x+1
plt.plot(X,2*X+1.0,'g',label='Object_Line',linewidth=4)
plt.plot(X,W[0]*X+b,'r',label='Fitted_Line',linewidth=3)
plt.legend(loc='upper left')
plt.show()
# 模型评估
cost = model.evaluate(X_test, Y_test, batch_size=40)
print('cost:', cost)
# 模型预测
pre1 = model.predict([2])# 求x=2时,y的预测值
print('2的预测值=',pre1[0][0],",实际值=",2*2+1.0)
# Y_pred = model.predict(X_test)
# plt.scatter(X_test,Y_test,c='r',label='Actual')
# plt.scatter(X_test,Y_pred,c='b',label='Pred')
# plt.legend()
# plt.show()
# 模型保存
model.save('test01.h5')
keras 手写体识别
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# with np.load('./data/mnist.npz') as data:
# x_train = data['x_train']
# y_train = data['y_train']
# x_test = data['x_test']
# y_test = data['y_test']
print(x_train.shape) # 显示数据集的维度
# (60000, 28, 28) 训练集⾥有60000个样本,每个图⽚样本是28像素×28像素的⼤⼩
from matplotlib import pyplot as plt
# print(type(x_train(0)))
plt.imshow(x_train[0])
plt.show()
# Model / data parameters
input_shape = (28, 28, 1)
num_classes = 10 #输出值的纬度,对应0-9的概率
# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
#
# 因为imshow()显示图像时对double型是认为在0~1范围内,即大于1时都是显示为白色,(虽然我的电脑没有)
# 而imshow显示uint8型时是0~255范围。而经过运算的范围在0-255之间的double型数据就被不正常得显示为白色图像了。
# x_train = x_train.astype("float32")
# x_test = x_test.astype("float32")
# plt.imshow(x_train[0])
# plt.show()
# Make sure images have shape (28, 28, 1)
x_train = np.expand_dims(x_train, -1) ##类似于扩建一维
x_test = np.expand_dims(x_test, -1)
print(x_train.shape, "train samples")
print(x_test.shape, "test samples")
# convert class vectors to binary class matrices
#将类向量转换为二进制类矩阵
print(y_train.shape)
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(y_train)
# 构建模型
model = keras.Sequential(
[
keras.Input(shape=input_shape),
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Flatten(),
layers.Dropout(0.5),
##这几行参数很重要
layers.Dense(num_classes, activation="softmax"),
] ) # 在构造⼀个对象时加⼊层Layer,当然也可以先产⽣⼀个Sequential对象,然后使⽤add⽅法加层Layer
model.summary()
# 编译模型
model.compile(loss="categorical_crossentropy",
optimizer="adam",
metrics=["accuracy"])
#训练
batch_size = 128
epochs = 2
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_split=0.1)
##预测
test_imge = x_test[10] #随便选择某个图
plt.imshow(test_imge)
plt.show()
data=np.expand_dims(test_imge, 0)
pre=model.predict([data])
# print(pre)# 显示预测值,为⻓度为10的量,分别对应数字0~9的概率
print("预测结果为:",np.argmax(pre))
#评估
score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])
#保存
fname = "/model_new.h5"
keras.models.save_model(model, fname)
# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# with np.load('./data/mnist.npz') as data:
# x_train = data['x_train']
# y_train = data['y_train']
# x_test = data['x_test']
# y_test = data['y_test']
print(x_train.shape) # 显示数据集的维度
# (60000, 28, 28) 训练集⾥有60000个样本,每个图⽚样本是28像素×28像素的⼤⼩
from matplotlib import pyplot as plt
# print(type(x_train(0)))
plt.imshow(x_train[0])
plt.show()
# Model / data parameters
input_shape = (28, 28, 1)
num_classes = 10 #输出值的纬度,对应0-9的概率
# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
#
# 因为imshow()显示图像时对double型是认为在0~1范围内,即大于1时都是显示为白色,(虽然我的电脑没有)
# 而imshow显示uint8型时是0~255范围。而经过运算的范围在0-255之间的double型数据就被不正常得显示为白色图像了。
# x_train = x_train.astype("float32")
# x_test = x_test.astype("float32")
# plt.imshow(x_train[0])
# plt.show()
# Make sure images have shape (28, 28, 1)
x_train = np.expand_dims(x_train, -1) ##类似于扩建一维
x_test = np.expand_dims(x_test, -1)
print(x_train.shape, "train samples")
print(x_test.shape, "test samples")
# convert class vectors to binary class matrices
#将类向量转换为二进制类矩阵
print(y_train.shape)
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print(y_train)
# 构建模型
model = keras.Sequential(
[
keras.Input(shape=input_shape),
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Flatten(),
layers.Dropout(0.5),
##这几行参数很重要
layers.Dense(num_classes, activation="softmax"),
] ) # 在构造⼀个对象时加⼊层Layer,当然也可以先产⽣⼀个Sequential对象,然后使⽤add⽅法加层Layer
model.summary()
# 编译模型
model.compile(loss="categorical_crossentropy",
optimizer="adam",
metrics=["accuracy"])
#训练
batch_size = 128
epochs = 2
model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_split=0.1)
##预测
test_imge = x_test[10] #随便选择某个图
plt.imshow(test_imge)
plt.show()
data=np.expand_dims(test_imge, 0)
pre=model.predict([data])
# print(pre)# 显示预测值,为⻓度为10的量,分别对应数字0~9的概率
print("预测结果为:",np.argmax(pre))
#评估
score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])
#保存
fname = "/model_new.h5"
keras.models.save_model(model, fname)
Tensorflow 将散点拟合为函数
# 导⼊需要的库包
import tensorflow as tf # 载⼊TensorFlow
import numpy as np # 载⼊numpy
import matplotlib.pyplot as plt # 载⼊matplotlib
# ⽣成⼈⼯数据集
x_data = np.linspace(-1,1,100) # 在-1到1之间,⽣成100点
# print(x_data)
np.random.seed(5) # 设置随机数种⼦
# y=2x + 1 + 噪声 其中噪声的维度和x_data⼀致
y_data = 2*x_data+1.0+np.random.randn(*x_data.shape)*0.4
y_data2=np.linspace(-1,1,100)
# 画出随机⽣成数据的散点图
plt.scatter(x_data,y_data)
# 画出想通过学习得到的⽬标线性函数y=2x+1
# plt.plot(x_data,1.0+2*x_data,'r',linewidth=3)
# plt.show()
# print(zip(x_data,y_data))
# 构造模型
def model(x,w,b):
return tf.multiply(x,w)+b
## 创建待优化的变量(待求参数)
# 构建模型中的变量w,对应线性函数的斜率
w = tf.Variable(np.random.randn(),tf.float32) #randn的括号内不填就只有一个值
#w是tf类型的 w.numpy()即可转换
# print('w=',w)
# 构建模型中的变量b,对应线性函数的截距
b = tf.Variable(0.0,tf.float32)
# 定义损失函数
def loss(x,y,w,b): #算的值是一个点的 #x y直接传入同纬度数组,最后也能只剩下最后一个值(因为返回的是平均值)
err= model(x,w,b)-y # 计算模型预测值与标签值之间的差异
squared_err = tf.square(err) # 求平⽅,得出⽅差
return tf.reduce_mean(squared_err) # 求均值,得出均⽅差
loss_ = loss(x_data, y_data, w, b)
# loss2=loss(1., 1., w, b)
# print(loss_)
# print(loss2)
# 定义计算梯度函数
# 计算样本数据[x,y] 在参数[w,b]点上的梯度
def grad(x,y,w,b):
with tf.GradientTape() as tape:
loss_=loss(x,y,w,b)
return tape.gradient(loss_,[w,b]) #梯度值与上一次的均方差有关
# # 执⾏训练,并显示中间结果
# # ⽅案1,使⽤GP(gradient descent)
# # 设置训练超参数
# training_epochs = 10 # 训练轮次
# learning_rate = 0.01 # 学习率
# step = 0 # 记录训练步数
# loss_list = [] # ⽤于保存loss值的列表
# display_step = 20 # 控制训练过程数据显示的频率
# for epoch in range(training_epochs): # 训练轮次
# for xs,ys in zip(x_data,y_data): # 每个数据训练⼀次 #打包(x,y)
# loss_=loss(xs,ys,w,b) # 计算损失
# loss_list.append(loss_) # 保存本次损失计算的结果
# delta_w,delta_b = grad(xs,ys,w,b)
# new_w=delta_w*learning_rate #降低梯度值*学习率
# new_b=delta_b*learning_rate
# w.assign_sub(new_w) # 变更参数w的值
# b.assign_sub(new_b) # 变更参数b的值
# step=step+1 # 训练步数+1
# if step % display_step==0:
# print("Training Epoch:",'%02d' % (epoch+1),"step:%03d" % (step),"loss=%.6f"% (loss_))
# #w b的值为一轮之后最后的值
# plt.plot(x_data,w.numpy() * x_data + b.numpy(),label=str(epoch)) # ⼀轮训练完后,画出回归的线条
#
# plt.legend() # 添加图列
# plt.show() # 显示图形
# # ⽅案2,使⽤BGP(Batch gradient descent)
# 执⾏训练,并显示中间结果
# 设置训练超参数
training_epochs = 20 # 训练轮次
learning_rate = 0.05 # 学习率
step = 0 # 记录训练步数
loss_list = [] # ⽤于保存loss值的列表
for epoch in range(training_epochs): # 训练轮次
loss_ = loss(x_data, y_data, w, b) # 计算损失
loss_list.append(loss_) # 保存本次损失计算的结果
delta_w, delta_b = grad(x_data, y_data, w, b)
new_w = delta_w * learning_rate
# print(x_data)
# print(delta_w)
# print(new_w)
new_b = delta_b * learning_rate
w.assign_sub(new_w) # 变更参数w的值
b.assign_sub(new_b) # 变更参数b的值
print("Training Epoch:", '%02d' % (epoch + 1), "loss=%.6f" % (loss_))
plt.plot(x_data, w.numpy() * x_data + b.numpy(), label=str(epoch)) # ⼀轮训练完后,画出回归的线条
plt.show()
###方法一是对一个个点计算loss 算完所有点后重复
###方法二是对所有点算的loss平均后给w b赋值,重复 方法二能保证每次重复的时候loss都在下降
##这个例子体现出的tensorflow的优势仅仅为 with tf.GradientTape() as tape: return tape.gradient(loss_,[w,b])
#如果numpy有对应的函数,似乎完全没必要用tensorflow