初次接触深度学习,记录一点思考和想法,请大家多多指正。

首先是工具包的导入pycharm

这里我用到了numpy科学计算库,json轻量级的数据交换格式包,以及matplotlib绘图工具包

import numpy as np
import json
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

 首先我们的目的是用13个有关因素预测房价,相当于有13个自变量x,1个输出y,我们要寻找这些x,与y之间的函数。

首先是数据的预处理

我们有大概500多个数据,类似于这样的形式,它们之间用空格分开。

 使用np.fromdata来读取数据记录在data一维数组中,sep参数我猜测是这个函数读取数据的方式,如果有空格分开就代表这空格两边各有一个数据。之后将data由一维的数组用reshape函数转化为一个14*506的数组矩阵,再将其中的80%的数据用来训练,20%的数据用来测试。随后对数据进行归一化处理,归一化的目的为了将来取下降梯度计算的detla值更方便,这里我也不太明白是为什么。

def load_data():
    datafile='/home/xiaobin0264/fzb/datafile/housing.data'
    data=np.fromfile(datafile,sep=' ')
    #定义十三个变量名
    feature_names = [ 'CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE','DIS',
                     'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV' ]
    feature_num = len(feature_names)
    data = data.reshape([data.shape[0] // feature_num, feature_num])
    ratio = 0.8
    offset = int(data.shape[0] * ratio)
    training_data = data[:offset]
    #求出训练数据的最大值最小值和平均值
    datamax,datamin,avgs=\
        training_data.max(axis=0),\
        training_data.min(axis=0),\
        training_data.sum(axis=0) / training_data.shape[0]
    for i in range(feature_num):
        print(datamin[i], datamin[i], avgs[i])
        data[:, i] = (data[:, i] - datamin[i]) / (datamax[i] - datamin[i])

    test_data = data[offset:]
    return training_data,test_data

training_data, test_data = load_data()
#x方向全选,y方向选到最后一组
x = training_data[:, :-1]
y = training_data[:, -1:]

将输入因素x,和输出房价y,分别从training_data训练数据中取出,建立一个神经网络的类Network将其中神经元权重的w,和b初始化,这里我用随机数初始化了13个w的权重,初始化偏置b为0

forwoard 函数为前向计算函数,作用是用来计算当前的权重和偏置下的预测值z

loss函数为损失函数,这里因为我们所预测的房价是一个连续的实数,因此我们使用均方差来计算预测值和实际值的损失,至于为什么用均方差不用绝对值差,是因为后面我们计算梯度下降时为了考虑到梯度的存在性,均方差会比绝对值差更好。

gradient 函数为梯度计算函数,我们为了使我们的loss函数最小,要找出一个w和一个b使loss处于最低点,但我们不知道何处是最低,所以我们先采用一个随机的w和b,通过计算函数梯度的梯度来判断此时我们的w和b处于一个怎样的趋势,若梯度为负值,我们增大自变量,函数值就会下降,反之则增大。所以为了求得最小值我们使用梯度下降的方法,通过不断地迭代计算,每次通过计算的梯度,对w和b进行反梯度的很小的移动。

update 函数为更新函数,对每次迭代后产生新的w,b进行更新,用来做下一次计算

train 函数 训练函数,将上述所有的操作整合

class Network(object):
    def __init__(self, num_of_weights):
        # 随机产生w的初始值
        # 为了保持程序每次运行结果的一致性,此处设置固定的随机数种子
        np.random.seed(0)
        self.w = np.random.randn(num_of_weights, 1)
        self.b = 0.

    def forward(self, x):
        z = np.dot(x, self.w) + self.b
        return z

    def loss(self, z, y):
        error = z - y
        cost = error * error
        cost = np.mean(cost)
        return cost

    def gradient(self, x, y):
        z = self.forward(x)
        gradient_w = (z - y) * x
        gradient_w = np.mean(gradient_w, axis=0)
        #这里增加axis轴是为了使梯度矩阵由横向矩阵变为竖向矩阵便于后面加减计算
        gradient_w = gradient_w[:, np.newaxis]
        gradient_b = (z - y)
        gradient_b = np.mean(gradient_b)
        return gradient_w, gradient_b
    def update(self,gradient_w,gradient_b,delta=0.01):
        self.w=self.w-gradient_w*delta
        self.b=self.b-gradient_b*delta
    def train(self,x, y,iterations=100,delta=0.01):
        losses=[]
        for i in range(iterations):
            z=self.forward(x)
            L=self.loss(z,y)
            gradient_w,gradient_b=self.gradient(x,y)
            self.update(gradient_w,gradient_b)
            losses.append(L)
            if (i+1)%10==0:
                print("itera={},loss={}".format(i,L))
        return losses

以下是代码的实现调用,用matplotlib显示训练的loss变化过程

train_data, test_data = load_data()
x = train_data[:, :-1]
y = train_data[:, -1:]
# 创建网络
net = Network(13)
num_iterations = 2000
# 启动训练
losses = net.train(x, y, iterations=num_iterations, delta=0.01)

# 画出损失函数的变化趋势
plot_x = np.arange(num_iterations)
plot_y = np.array(losses)
plt.plot(plot_x, plot_y)

结果是这样

y轴是losses损失,x轴是迭代次数

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐