IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> numpy简单神经网络学习mnist -> 正文阅读

[人工智能]numpy简单神经网络学习mnist

numpy实现最简单的前馈神经网络——正向网络建立篇

根据上一篇文章,来构建神经网络吧

  1. 明确输入和输出
  2. 选择合适的各种函数
  3. 矩阵激活函数建立起从输入到输出的拟合函数
  4. 正向传播或反向传播获得损失函数的偏导数(注意对一定的数据集来说自变量为 W \bold{W} W A \bold{A} A固定)
  5. 梯度下降法努力使损失函数最小

mnist分析(输入分析)

下载

这里下载mnist数据集

关于mnist的详细说明在其他人的文章里有

说明

images前16个字节包含了数据的说明,之后的所有字节以 784 784 784字节为一组,是一个个 28 × 28 28\times28 28×28像素的图像,像素为一字节的灰度像素

labels前8个字节包含了数据的说明,之后的所有字节以 1 1 1字节为一组,是一个个对应着images中图像的数字

加载

以下函数的关键点在于np.fromfile()以及dtype, offset参数

import numpy as np

from os import listdir
from typing import Dict, NoReturn

S = 784               # area of image
C = 28                # edge length of image

def load_data(dir_path: str) -> Dict[str, np.ndarray]:
    """
    加载图像和标签
    load images and labels
    :param dir_path: directory that contains training files and test files
    """
    resource = {}
    file_names = listdir(dir_path)
    for file_name in file_names:
        full_path = path.join(dir_path, file_name)
        name, _ = path.splitext(file_name)
        if "images" in name:
            images = np.fromfile(full_path, dtype=np.uint8, offset=16)
            resource[name] = images.reshape(images.size // S, S)
        elif "labels" in name:
            labels = np.fromfile(full_path, dtype=np.uint8, offset=8)
            resource[name] = labels
    return resource

# images.shape == (60000, 784)
# labels.shape == (10000, )

显示

from PIL import Image

def display_images(resource, row: int, column: int,
                   interval: slice = slice(None, None, None)) -> NoReturn:
    """
    将多个图像显示在一张图像上
    :param row: 行数
    :param column: 列数
    :param interval: 图像区间
    """
    images = Image.new("L", (column * C, row * C))
    resource = resource["t10k-images"][interval]
    for i in range(column):
        for j in range(row):
            index = i * row + j
            array = resource[index].reshape(C, C)
            img = Image.fromarray(array)
            images.paste(img, (i * 28, j * 28))
    images.show()   # 效果如下

mnist数据显示

输出分析

显然,输出是10个数字中的一个,也就是预测结果。但是一个结果难以使用损失函数确定拟合程度,所以我们希望输出是一个长度为10的向量,包含了每个数字的预测概率

通过普通的矩阵函数产生的输出不一定是概率(就是相加为1且没有负数),可以通过softmax()矫正
s o f t m a x ( e i ) = e i ∑ i e softmax(e_i)=\frac{e_i}{\sum_i{e}} \\ softmax(ei?)=i?eei??

def softmax(x: np.ndarray) -> np.ndarray:
    t = np.exp(x - x.max())
    y = np.sum(t, axis=1).reshape(t.shape[0], 1)
    return t / y

由输出的概率和标签,通过交叉熵损失函数算出损失

def cross_entropy_error(result: np.ndarray, labels: np.ndarray) -> np.ndarray:
    """
    交叉熵损失函数
    :param result: 长度为10的向量,包含每个数字的预测概率
    :param labels: 图像的标签,即图像的真实数字
    """
    return -np.sum(np.log(result[np.arange(labels.size), labels] + 1e-7))

拟合函数建立

激活函数

由于计算过程中可能会出现一定程度的上溢或下溢,并且数字过大也会影响计算

可以使用值域在 ( 0 , 1 ) (0,1) (0,1)sigmoid(),同时它的导数也很好计算
s i g m o i d ( x ) = 1 1 + e ? z . s i g m o i d ( x ) ∈ ( 0 , 1 ) s i g m o i d ′ ( x ) = e ? z ( 1 + e ? z ) 2 = [ 1 ? s i g m o i d ( x ) ] ? s i g m o i d ( x ) sigmoid(x) = \frac{1}{1+e^{-z}}. \\ sigmoid(x) \in (0,1) \\ sigmoid'(x) = \frac{e^{?z}}{(1+e^{?z})^2} = [1-sigmoid(x)] \cdot sigmoid(x) sigmoid(x)=1+e?z1?.sigmoid(x)(0,1)sigmoid(x)=(1+e?z)2e?z?=[1?sigmoid(x)]?sigmoid(x)

def sigmoid(x: np.ndarray) -> np.ndarray:
    return 1 / (1 + np.exp(-x))

def derivative_sigmoid(x: np.ndarray) -> np.ndarray:
    y = sigmoid(x)
    return (1 - y) * y

拟合函数

只是演示代码,并不能一定运行

def predict(input_images: np.ndarray, layer_count: int, W: np.ndarray, B: np.ndarray) -> np.ndarray:
    """
    获得预测结果的概率
    obtain the probabilities of results (namely 0-9)
    :param W: 矩阵数组
    :param B: 偏置数组
    :return: 预测结果概率
    """
    layer = input_images
    for i in range(layer_count):
        layer = sigmoid(layer @ W[i]) + B[i]
    layer = soft_max(layer)
    return layer

# 如果a, b都是np.ndarray
# 那么
# a.dot(b)
# np.dot(a, b)
# a @ b
# 都代表矩阵乘法

input_images就是待预测图像( 28 × 28 28 \times 28 28×28字节),layer_count是神经网络层数,W是权重也就是矩阵函数,B是偏置

这样就完成了一次预测,当然最后的代码会复杂很多

正向计算梯度

只是演示代码,并不能一定运行

def numerical_gradient(input_images: np.ndarray,
                       w_grad: np.ndarray,
                       b_grad: np.ndarray) -> NoReturn:
    """
    正向求梯度
    forward gradient
    :param step_length: 训练步长,学习率 learning rate
    """
    h = 1e-5         # 求偏导数需要的微小量
    for i in range(W.size):
        for j in range(W[i].size):
            # 这里就是用偏导数定义求偏导数
	        t = W[i, j]

            W[i, j] = t - h
            f1 = loss(predict())
            W[i, j] = t + h
            f2 = loss(predict())

        	w_grad[i, j] = (f2 - f1) / (2 * h)

        W[i, j] = t
	
    for i in range(B.size):
        for j in range(B[i].size):
	        t = B[i, j]

            B[i, j] = t - h
            f1 = loss(predict())
            B[i, j] = t + h
            f2 = loss(predict())

        	b_grad[i, j] = (f2 - f1) / (2 * h)

        B[i, j] = t

w_grad是权重的梯度,b_grad是偏置的梯度,这样就用梯度下降法了

梯度下降

learning_rate = 0.02

W -= w_grad * learning_rate
B -= b_grad * learning_rate

完成一次梯度下降!

多次重复即可提高拟合度

由于正向求梯度,该方法非常缓慢,可能需要3-4天才能有80%-90%的准确率

下一篇会介绍反向求梯度,可以在十几分钟内达到90%的准确率

最终代码

feedforward-mnist

我也是第一次用github,其他不会用,只放了代码

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-09-09 11:45:02  更:2021-09-09 11:47:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 15:51:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码