刘二大人
学习 pytorch
完成的课后作业,原视频请戳这里计算损失
,还要 使用 matplotlib 绘制 3D 图像
train_x = [1.0, 2.0, 3.0]
train_y = [2.0, 4.0, 6.0]
w
,b
,所以我们使用双层循环遍历他们的每一个组合,并计算预测值与真实值之间的均差,即 loss
,使用 DataFrame
存取数据,代码如下import numpy as np
import pandas as pd
def forward(w, x, b):
return w * x + b
def process(w, x, b, y):
y_pred = forward(w, x, b)
return pow(y_pred - y, 2)
w_list = np.arange(0.0, 6.1, 0.1) # arange 左闭右开
b_list = np.arange(-6.0, 6.1, 0.1)
result = []
for w_index, w in enumerate(self.w):
for b_index, b in enumerate(self.b):
losses = pd.Series([0.0])
for x, y in zip(self.X, self.y):
losses = losses.append(pd.Series(process(w, x, b, y)))
result.loc[result.shape[0]+1] = (w, b, losses.std())
print(result)
---------------------------------
w b loss
1 -6.0 -6.0 390.969735
2 -6.0 -5.9 388.531712
3 -6.0 -5.8 386.101901
4 -6.0 -5.7 383.680285
5 -6.0 -5.6 381.266851
... ... ... ...
14637 6.0 5.6 132.347889
14638 6.0 5.7 133.795879
14639 6.0 5.8 135.252733
14640 6.0 5.9 136.718468
14641 6.0 6.0 138.193102
matplotlib
绘制 3D
图像,这里我选用 Axes3D
,我们看一下官方样例array
,其中 np.meshgrid
作用是将两个一维的转换成两个二维的x, y = np.meshgrid(result['w'], result['b'])
z = result['loss']
fig = plt.figure()
ax = Axes3D(fig)
fig.add_axes(ax)
ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap=cm.viridis)
plt.show()
ValueError: Argument Z must be 2-dimensional.
z
必须得是个二维的数组result['loss'].to_frame()
一下可以吗?
shape mismatch: objects cannot be broadcast to a single shape
z = np.array(result['loss']).reshape(x.shape[0], -1) # -1 表示不晓得这个是多少,要根据数据量和已知维度来判断
遍历
(遍历 yyds
,虽然会很慢)z = []
for x_, y_ in zip(x, y):
z_ = []
for w, b in zip(x_, y_):
loss = data[(data['w'] == w) & (data['b'] == b)]['loss'].values[0]
z_.append(loss)
z.append(z_)
x, y = np.meshgrid(data['w'].drop_duplicates(), data['b'].drop_duplicates())
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
class train:
def __init__(self, X, y, w_limit, b_limit, span=0.1):
self.X = X
self.y = y
self.w = np.arange(w_limit[0], w_limit[1] + span, span)
self.b = np.arange(b_limit[0], b_limit[1] + span, span)
self.result = pd.DataFrame(columns=['w', 'b', 'loss'])
# 预测
def __forward(self, w, x, b):
return w * x + b
# 计算损失
def __loss(self, w, x, b, y):
y_pred = self.__forward(w, x, b)
return pow(y-y_pred, 2)
def process(self):
for w in self.w:
print('w = {:>.2f}'.format(w))
for b_index, b in enumerate(self.b):
losses = []
count = b_index + 1
for x, y in zip(self.X, self.y):
losses.append(self.__loss(w, x, b, y))
self.result.loc[self.result.shape[0]+1] = (w, b, sum(losses) / len(losses))
min_index = self.result[self.result['w'] == w].sort_values(by='loss').iloc[0]
print('\r{:>6.2f}%: [{}{}] b={:>.2f} min_loss={:>.2f}'.format(
count / len(self.b) * 100,
'■' * int(count / len(self.b) * 20),
'□' * (20 - int(count / len(self.b) * 20)),
min_index['b'], min_index['loss']
), end='')
print()
print('loss: %f' % (self.result['loss'].std()))
def get_result(self):
return self.result
train_x = [1.0, 2.0, 3.0]
train_y = [2.0, 4.0, 6.0]
model = train(train_x, train_y, (-3.0, 6.0), (-6.0, 6.0), 0.1)
model.process()
data = model.get_result()
x, y = np.meshgrid(data['w'].drop_duplicates(), data['b'].drop_duplicates())
z = []
for x_, y_ in zip(x, y):
z_ = []
for w, b in zip(x_, y_):
# 找到对应的 loss
loss = data[(data['w'] == w) & (data['b'] == b)]['loss'].values[0]
z_.append(loss)
z.append(z_)
z = np.array(z)
fig = plt.figure()
ax = Axes3D(fig)
fig.add_axes(ax)
ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap=cm.viridis)
plt.show()
class train:
def __init__(self, X, y, w_limit, b_limit, span=0.1):
self.X = np.array(X) if type(X) == list else X
self.y = np.array(y) if type(y) == list else y
self.w = np.arange(w_limit[0], w_limit[1] + span, span)
self.b = np.arange(b_limit[0], b_limit[1] + span, span)
self.result = pd.DataFrame(columns=['w', 'b', 'loss'])
def __forward(self, w, X, b):
return w * X + b
def __loss(self, y, y_pred):
return pow(y - y_pred, 2)
def process(self):
for w in self.w:
print('w = {:>.2f}'.format(w))
for b_index, b in enumerate(self.b):
count = b_index + 1
y_pred = self.__forward(w, self.X, b)
loss = self.__loss(self.y, y_pred)
self.result.loc[self.result.shape[0]+1] = (w, b, loss.sum() / loss.shape[0])
min_index = self.result[self.result['w'] == w].sort_values(by='loss').iloc[0]
print('\r{:>6.2f}%: [{}{}] b={:>.2f} min_loss={:>.2f}'.format(
count / len(self.b) * 100,
'■' * int(count / len(self.b) * 20),
'□' * (20 - int(count / len(self.b) * 20)),
min_index['b'], min_index['loss']
), end='')
print()
print('loss: %f' % (self.result['loss'].std()))
def get_result(self):
return self.result
以上就是我要分享的内容,因为学识尚浅,会有不足,还请各位大佬指正。
有什么问题也可在评论区留言。