人工智能第三次作业

一、绪论

项目 内容
这个作业属于哪个课程 [人工智能](https://edu.cnblogs.com/campus/buaa/BUAA-AI-2019)
这个作业的要求在哪里 [作业要求](https://edu.cnblogs.com/campus/buaa/BUAA-AI-2019/homework/2787)
我在这个课程的目标是 学习了解应用人工智能
这个作业在哪个具体方面帮助我实现目标 学习Mini Batch梯度下降方法
#二、代码实现 ``` import numpy as np import matplotlib.pyplot as plt from pathlib import Path

x_data_name = "TemperatureControlXData.dat"
y_data_name = "TemperatureControlYData.dat"

class CData(object):
def init(self, loss, w, b, epoch, iteration):
self.loss = loss
self.w = w
self.b = b
self.epoch = epoch
self.iteration = iteration

def ReadData():
Xfile = Path(x_data_name)
Yfile = Path(y_data_name)
if Xfile.exists() & Yfile.exists():
X = np.load(Xfile)
Y = np.load(Yfile)
return X.reshape(1,-1),Y.reshape(1,-1)
else:
return None,None

def ForwardCalculationBatch(W,B,batch_x):
Z = np.dot(W, batch_x) + B
return Z

def BackPropagationBatch(batch_x, batch_y, batch_z):
m = batch_x.shape[1]
dZ = batch_z - batch_y
dB = dZ.sum(axis=1, keepdims=True)/m
dW = np.dot(dZ, batch_x.T)/m
return dW, dB

def UpdateWeights(w, b, dW, dB, eta):
w = w - etadW
b = b - eta
dB
return w,b

def InitialWeights(num_input, num_output, flag):
if flag == 0:
# zero
W = np.zeros((num_output, num_input))
elif flag == 1:
# normalize
W = np.random.normal(size=(num_output, num_input))
elif flag == 2:
# xavier
W=np.random.uniform(
-np.sqrt(6/(num_input+num_output)),
np.sqrt(6/(num_input+num_output)),
size=(num_output,num_input))

B = np.zeros((num_output, 1))
return W,B

def CheckLoss(W, B, X, Y):
m = X.shape[1]
Z = np.dot(W, X) + B
LOSS = (Z - Y)**2
loss = LOSS.sum()/m/2
return loss

def ShowResult(X, Y, w, b, iteration):
# draw sample data
plt.plot(X, Y, "b.")
# draw predication data
PX = np.linspace(0,1,10)
PZ = w*PX + b
plt.plot(PX, PZ, "r")
plt.title("Air Conditioner Power")
plt.xlabel("Number of Servers(K)")
plt.ylabel("Power of Air Conditioner(KW)")
plt.show()
print("iteration=",iteration)
print("w=%f,b=%f" %(w,b))

def GetBatchSamples(X,Y,batch_size,iteration):
num_feature = X.shape[0]
start = iteration * batch_size
end = start + batch_size
batch_x = X[0:num_feature,start:end].reshape(num_feature,batch_size)
batch_y = Y[0,start:end].reshape(1,batch_size)
return batch_x, batch_y

def Shuffle(X, Y):
seed = np.random.randint(0,100)
np.random.seed(seed)
XP = np.random.permutation(X.T)
np.random.seed(seed)
YP = np.random.permutation(Y.T)
return XP.T, YP.T

def GetMinimalLossData(dict_loss):
key = sorted(dict_loss.keys())[0]
w = dict_loss[key].w
b = dict_loss[key].b
return w,b,dict_loss[key]

def ShowLossHistory(dict_loss, method):
loss = []
for key in dict_loss:
loss.append(key)

#plt.plot(loss)
plt.plot(loss[30:800])
plt.title(method)
plt.xlabel("epoch")
plt.ylabel("loss")
plt.show()

def loss_2d(x,y,n,dict_loss,method,cdata):

result_w = cdata.w[0,0]
result_b = cdata.b[0,0]

# show contour of loss
s = 150
W = np.linspace(result_w-1,result_w+1,s)
B = np.linspace(result_b-1,result_b+1,s)
LOSS = np.zeros((s,s))
for i in range(len(W)):
    for j in range(len(B)):
        w = W[i]
        b = B[j]
        a = w * x + b
        loss = CheckLoss(w,b,x,y)
        LOSS[i,j] = np.round(loss, 2)
    # end for j
# end for i
print("please wait for 20 seconds...")
while(True):
    X = []
    Y = []
    is_first = True
    loss = 0
    for i in range(len(W)):
        for j in range(len(B)):
            if LOSS[i,j] != 0:
                if is_first:
                    loss = LOSS[i,j]
                    X.append(W[i])
                    Y.append(B[j])
                    LOSS[i,j] = 0
                    is_first = False
                elif LOSS[i,j] == loss:
                    X.append(W[i])
                    Y.append(B[j])
                    LOSS[i,j] = 0
                # end if
            # end if
        # end for j
    # end for i
    if is_first == True:
        break
    plt.plot(X,Y,'.')
# end while

# show w,b trace
w_history = []
b_history = []
for key in dict_loss:
    w = dict_loss[key].w[0,0]
    b = dict_loss[key].b[0,0]
    if w < result_w-1 or result_b-1 < 2:
        continue
    if key == cdata.loss:
        break
    # end if
    w_history.append(w)
    b_history.append(b)
# end for
plt.plot(w_history,b_history)

plt.xlabel("w")
plt.ylabel("b")
title = str.format("Method={0}, Epoch={1}, Iteration={2}, Loss={3:.3f}, W={4:.3f}, B={5:.3f}", method, cdata.epoch, cdata.iteration, cdata.loss, cdata.w[0,0], cdata.b[0,0])
plt.title(title)
plt.show()

if name == 'main':

# 修改method分别为下面三个参数,运行程序,对比不同的运行结果
# SGD, MiniBatch, FullBatch
eta = 0.1
max_epoch = 50
batch_size = 5
method = "batch_size="+str(batch_size)

W, B = InitialWeights(1,1,0)
# calculate loss to decide the stop condition
loss = 5
dict_loss = {}
# read data
X, Y = ReadData()
# count of samples
num_example = X.shape[1]
num_feature = X.shape[0]


# if num_example=200, batch_size=10, then iteration=200/10=20
max_iteration = (int)(num_example / batch_size)
for epoch in range(max_epoch):
    #print("epoch=%d" %epoch)
    for iteration in range(max_iteration):
        # get x and y value for one sample
        batch_x, batch_y = GetBatchSamples(X,Y,batch_size,iteration)
        # get z from x,y
        batch_z = ForwardCalculationBatch(W, B, batch_x)
        # calculate gradient of w and b
        dW, dB = BackPropagationBatch(batch_x, batch_y, batch_z)
        # update w,b
        W, B = UpdateWeights(W, B, dW, dB, eta)
        
        # calculate loss for this batch
        loss = CheckLoss(W,B,X,Y)
        #print(epoch,iteration,loss,W,B)
        prev_loss = loss

        dict_loss[loss] = CData(loss, W, B, epoch, iteration)            
    # end for
    #X,Y = Shuffle(X,Y)
# end for

ShowLossHistory(dict_loss, method)
w,b,cdata = GetMinimalLossData(dict_loss)
print(cdata.w, cdata.b)
print("epoch=%d, iteration=%d, loss=%f" %(cdata.epoch, cdata.iteration, cdata.loss))

#ShowResult(X, Y, W, B, epoch)
print(w,b)

x = 346/1000
result = ForwardCalculationBatch(w, b, x)
print(result)

loss_2d(X,Y,200,dict_loss,method,cdata)

#三、结果展示
epoch=5
![](https://img2018.cnblogs.com/blog/1616671/201904/1616671-20190422231840284-1126430937.png)

![](https://img2018.cnblogs.com/blog/1616671/201904/1616671-20190422231905312-959603957.png)
输出结果:

w=1.99619285,b=3.00559685

epoch=10
![](https://img2018.cnblogs.com/blog/1616671/201904/1616671-20190422232310530-931248677.png)

![](https://img2018.cnblogs.com/blog/1616671/201904/1616671-20190422232321876-1436635489.png)
输出结果:

w=1.996016744958851,b=3.0051812577208974

epoch=15
![](https://img2018.cnblogs.com/blog/1616671/201904/1616671-20190422232614815-139478863.png)

![](https://img2018.cnblogs.com/blog/1616671/201904/1616671-20190422232626699-485063374.png)
输出结果:

w=1.994684,b=3.006479

#四、问题
问题二:因为w和b的影响权重实时发生变化,当对于实际数据进行特定调整状态下,可以变成一个圆
问题三:我们对于w和b的取值是离散的,因此无法完美的到一个值,而是只能通过无限逼近的方式锁定一个范围。

posted on 2019-03-25 19:00  tk1763  阅读(219)  评论(1)    收藏  举报