单神经元人工智能网络编程及源码

相关介绍

目前在在跟着大佬学习人工智能,学了两个章节后,感觉自己学的不是很通透,所以想试试写下来会不会好一点,也是给自己做一个总结。
人工智能算法,是仿照人大脑中神经元的构成和运行的机制所提出的算法。在这里插入图片描述
上图就是一个神经元的示意图,从多个触角上进行输入,每个触角的权重不相同,权重与触角的输入相乘后决定一个人的行为。就比如说一个人面对水,他把手伸进去,决定他要不要拿出来的因素有几个,比如说水的温度,外界的温度,个人的体温等等,每个都有不同的权重。第一次不知道水温的时候,就是试探,之后再决定伸进去与否,这个过程就是权重的调节。而人工智能就是仿照这么一个过程,在不断调节权重的过程中,最终实现想要的结果的一个过程。
这几天学习了一个单神经元的人工智能算法,对于是或者不是的选择上有着比较好的应用。下面,我就分享一个单神经元情况下的人工智能算法的思路和代码。上文我们说到,人工智能算法是一个不断计算和调节的过程,想必大家高中的时候就学过求导的运算,但是那个时候的其实算是一种理想情况的求导,而现在我们需要利用实际的计算值实现实际值和理想值之间的误差,在通过学习率调节权重变化的速率,最终达到相对理想的一个权重效果。
既然涉及到求导的问题,这里需要大家去复习一下链式法则(这个以后的博文会出现,本文只是人工智能的一个记录帖),通过链式法则进行反向求导。下面我先展示一下,单个神经元的人工智能算法的思维导图:
在这里插入图片描述
之后是涉及到的一些函数及相关函数用法的简单表达(更复杂的以后会相继给大家更新):
在这里插入图片描述

所需函数

以上便是各种函数以及各种函数的用法,下面进入实战环节:
首先我们要加载几个用到的库:

import numpy as np #科学计算的库
import matplotlib.pyplot as plt  #画图的库
import h5py  #h5数据类型读取的库

数据的读取和存储

我们要实现数据的读取,先编写一个能够读取数据集的函数:

def load_data():
    train_dataset = h5py.File('datasets/train_catvnoncat.h5',"r")  #加载训练数据集
    train_set_x_orig = np.array(train_dataset["train_set_x"][ : ])  #加载数据集中的图片特征数据
    train_set_y_orig = np.array(train_dataset["train_set_y"][ : ])  #加载标签数据(已经预处理过,确定了那些是那些不是)

    test_dataset = h5py.File('datasets/test_catvnoncat.h5',"r")  #加载测试数据集
    test_set_x_orig = np.array(test_dataset["test_set_x"][:])
    test_set_y_orig = np.array(test_dataset["test_set_y"][:])

    classes = np.array(test_dataset["list_classes"][ : ])  #加载标签类别数据
    
    train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))  # 把数组的维度从(209,)变成(1, 209)
    test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))  # 从(50,)变成(1, 50)

    return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes

激活函数

激活函数在思维导图中也写了,是为了提高学习的效率和最后的结果,也就是提升整个人工智能的智商。前面所进行的计算全都是线性的,而激活函数最大的最用就是打破线性的约束条件,强化网络学习的能力,所以激活函数最大的特点就是非线性,而且不同的激活函数也有不同的特点。常用的激活函数大家可以转到下面这个帖子去看看:链接: https://zhuanlan.zhihu.com/p/73214810.
本次单个神经元的网络使用的是Sigmoid函数,函数的值域是(0,1):

def sigmoid(z):
        s = 1 / (1 + np.exp(-z)) #z可以是一个数值,也可以是一个数组,结果与之相对应
    return s

参数初始化

在单个神经元的人工智能函数中,可以对权重数组w和偏量数组b(个人觉得有点像线性回归函数里后面在y轴上的轴距)全部初始化为0(神经网络中是不可以对权重设置为0的):

def initialize_with_zeros(dim):
    w = np.zeros((dim, 1))
    b = 0
    return w, b

损失函数

损失函数,就是利用正向传导(学习已知结果的图片)和反向传导(计算误差,也就是求导的过程)实现对参数变化过程的计算,方便在学习函数中进行参数的学习和调节。损失函数的种类也有很多种,需要根据自己的实际需要进行选择,有需要的可以看看下面这个帖子:链接: https://zhuanlan.zhihu.com/p/58883095.下面使用的是交叉熵损失函数:

def propagate(w, b, X, Y):
    m = X.shape[1]
    # 前向传播
    A = sigmoid(np.dot(w.T, X) + b)
    cost = -np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A)) / m
    # 反向传播
    dZ = A - Y
    dw = np.dot(X, dZ.T) / m
    db = np.sum(dZ) / m
    # 将dw和db保存到字典里面,这里就是确定权重和偏置量变化量的过程
    grads = {"dw": dw,
             "db": db}
    return grads, cost

学习函数

学习,顾名思义:就像人类学习的过程一样,通过不断微调自己的行为达到一个自己理想值的情况,每个人的学习过程也受到个人天赋的影响,学习率高,就少学几次;学习率低可能就需要多学几次。但是数学计算的过程却非常容易因为取值的不合理,在极值附近反复横跳达不到好的结果,所以每次学习的时候,需要根据实际的情况设置学习率,在实验中进行调节。

def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost=False):
    costs = []
    for i in range(num_iterations):
        grads, cost = propagate(w, b, X, Y)  # 计算得出梯度和成本
        # 从字典中取出梯度
        dw = grads["dw"]
        db = grads["db"]
        '''
        下面的learning_rate就是学习率的意思,通过学习率的计算,最终实现对权重和偏置的确定
        '''
        w = w - learning_rate * dw
        b = b - learning_rate * db
        # 将成本记录下来
        if i % 100 == 0:
            costs.append(cost)
            if print_cost:
                print("优化%i次后成本是: %f" % (i, cost))

    params = {"w": w,
              "b": b}
    return params, costs

预测函数

这个函数是为了检测在不同学习率情况下预测的准确率(实际编程中,需要准确率时,可以写):
def predict(w, b, X):

def predict(w, b, X):  
    m = X.shape[1]
    Y_prediction = np.zeros((1, m))
    A = sigmoid(np.dot(w.T, X) + b)  # 通过这行代码来对图片进行预测
    # 上面得出的预测结果是小数的形式,为了方便后面显示,我们将其转换成0和1的形式(大于等于0.5就是1/有猫,小于0.5就是0/无猫)
    for i in range(A.shape[1]):
        if A[0, i] >= 0.5:
            Y_prediction[0, i] = 1
    return Y_prediction

模型函数

通过模型函数,实现对训练数据的学习,和对测试数据的测试

def model(X_train, Y_train, X_test, Y_test, num_iterations=2000, learning_rate=0.5, print_cost=False):
    # 初始化待训练的参数
    w, b = initialize_with_zeros(X_train.shape[0])
    # 使用训练数据来训练/优化参数
    parameters, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)
    # 从字典中分别取出训练好的w和b
    w = parameters["w"]
    b = parameters["b"]
    # 使用训练好的w和b来分别对训练图片和测试图片进行预测
    Y_prediction_train = predict(w, b, X_train)
    Y_prediction_test = predict(w, b, X_test)
    # 打印出预测的准确率
    print("对训练图片的预测准确率为: {}%".format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100))
    print("对测试图片的预测准确率为: {}%".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100))
    d = {"costs": costs,
         "Y_prediction_test": Y_prediction_test,
         "Y_prediction_train": Y_prediction_train,
         "w": w,
         "b": b,
         "learning_rate": learning_rate,
         "num_iterations": num_iterations}
    return d   

源码

以上便是需要用到的所有函数的编写,下面则是单个神经元人工智能的源码:

import numpy as np
import matplotlib.pyplot as plt 
import h5py             
import skimage.transform as tf
def load_dataset():
    train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")  
    train_set_x_orig = np.array(train_dataset["train_set_x"][:])  
    train_set_y_orig = np.array(train_dataset["train_set_y"][:])  
    test_dataset = h5py.File('datasets/test_catvnoncat.h5', "r") 
    test_set_x_orig = np.array(test_dataset["test_set_x"][:])
    test_set_y_orig = np.array(test_dataset["test_set_y"][:])
    classes = np.array(test_dataset["list_classes"][:])  
    train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0])) 
    test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))  # 从(50,)变成(1, 50)
    return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
train_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()
index = 0
plt.imshow(train_set_x_orig[index])
print ("标签为" + str(train_set_y[:, index]) + ", 这是一个'" + classes[np.squeeze(train_set_y[:, index])].decode("utf-8") +  "' 图片.")
#把他们的维度打印出来。
print ("train_set_x_orig shape: " + str(train_set_x_orig.shape))
print ("train_set_y shape: " + str(train_set_y.shape))
print ("test_set_x_orig shape: " + str(test_set_x_orig.shape))
print ("test_set_y shape: " + str(test_set_y.shape))
m_train = train_set_x_orig.shape[0]
m_test = test_set_x_orig.shape[0]
num_px = test_set_x_orig.shape[1] # 由于我们的图片是正方形的,所以长宽相等
print ("训练样本数: m_train = " + str(m_train))
print ("测试样本数: m_test = " + str(m_test))
print ("每张图片的宽/高: num_px = " + str(num_px))


train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0], -1).T
test_set_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T

print ("train_set_x_flatten shape: " + str(train_set_x_flatten.shape))
print ("test_set_x_flatten shape: " + str(test_set_x_flatten.shape))

train_set_x = train_set_x_flatten/255.
test_set_x = test_set_x_flatten/255.
def sigmoid(z):
     s = 1 / (1 + np.exp(-z))
    return s
def initialize_with_zeros(dim):
    w = np.zeros((dim, 1))
    b = 0
    return w, b


def propagate(w, b, X, Y):
    m = X.shape[1]

    # 前向传播
    A = sigmoid(np.dot(w.T, X) + b)
    cost = -np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A)) / m

    # 反向传播
    dZ = A - Y
    dw = np.dot(X, dZ.T) / m
    db = np.sum(dZ) / m

    # 将dw和db保存到字典里面
    grads = {"dw": dw,
             "db": db}

    return grads, cost
def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost=False):
    costs = []

    for i in range(num_iterations):
        grads, cost = propagate(w, b, X, Y)  # 计算得出梯度和成本

        # 从字典中取出梯度
        dw = grads["dw"]
        db = grads["db"]
        # 进行梯度下降,更新参数,使其越来越优化,使成本越来越小
        w = w - learning_rate * dw
        b = b - learning_rate * db
        # 将成本记录下来
        if i % 100 == 0:
            costs.append(cost)
            if print_cost:
                print("优化%i次后成本是: %f" % (i, cost))

    params = {"w": w,
              "b": b}
    return params, costs

def predict(w, b, X):
    m = X.shape[1]
    Y_prediction = np.zeros((1, m))

    A = sigmoid(np.dot(w.T, X) + b)  # 通过这行代码来对图片进行预测
    # 上面得出的预测结果是小数的形式,为了方便后面显示,我们将其转换成0和1的形式(大于等于0.5就是1/有猫,小于0.5就是0/无猫)
    for i in range(A.shape[1]):
        if A[0, i] >= 0.5:
            Y_prediction[0, i] = 1

    return Y_prediction


def model(X_train, Y_train, X_test, Y_test, num_iterations=2000, learning_rate=0.5, print_cost=False):
    # 初始化待训练的参数
    w, b = initialize_with_zeros(X_train.shape[0])

    # 使用训练数据来训练/优化参数
    parameters, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)

    # 从字典中分别取出训练好的w和b
    w = parameters["w"]
    b = parameters["b"]

    # 使用训练好的w和b来分别对训练图片和测试图片进行预测
    Y_prediction_train = predict(w, b, X_train)
    Y_prediction_test = predict(w, b, X_test)

    # 打印出预测的准确率
    print("对训练图片的预测准确率为: {}%".format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100))
    print("对测试图片的预测准确率为: {}%".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100))

    d = {"costs": costs,
         "Y_prediction_test": Y_prediction_test,
         "Y_prediction_train": Y_prediction_train,
         "w": w,
         "b": b,
         "learning_rate": learning_rate,
         "num_iterations": num_iterations}

    return d
# 调用上面的模型函数对我们最开始加载的数据进行训练
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 2000, learning_rate = 0.005, print_cost = True)
# 这里我们可以改变index,来看看哪些图片预测对了
index = 30
plt.imshow(test_set_x[:,index].reshape((num_px, num_px, 3)))
print ("这张图的标签是 " + str(test_set_y[0,index]) + ", 预测结果是 " + str(int(d["Y_prediction_test"][0,index])))
# 下面我们打印出成本随着训练次数增加时的变化情况。可以很直观的看出,训练次数越多,成本越小,也就是预测结果更精确
costs = np.squeeze(d['costs'])
plt.plot(costs)
plt.ylabel('cost') # 成本
plt.xlabel('iterations (per hundreds)') # 横坐标为训练次数,以100为单位
plt.title("Learning rate =" + str(d["learning_rate"]))
plt.show()
learning_rates = [0.01, 0.001, 0.0001]
models = {}
for i in learning_rates:
    print ("学习率为: " + str(i) + "时")
    models[str(i)] = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 1500, learning_rate = i, print_cost = False)
    print ('\n' + "-------------------------------------------------------" + '\n')

for i in learning_rates:
    plt.plot(np.squeeze(models[str(i)]["costs"]), label= str(models[str(i)]["learning_rate"]))

plt.ylabel('cost')
plt.xlabel('iterations (hundreds)')

legend = plt.legend(loc='upper center', shadow=True)
frame = legend.get_frame()
frame.set_facecolor('0.90')
plt.show()

以上便是单个神经元人工智能的学习全部内容,我学习的老师是床长,大家有兴趣的可以去他的微博学习,传送门如下:http://blog.csdn.net/jiangjunshow.

感谢床长的教程

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值