小案例的实现

案例背景:输入一个X(人工识别这个X的图像为狗)让机器自动判断该图像的分类,其中,图像为三分类(类别为鸡、猫、狗),真实标签的分类为y=[0,0,1](已经转换为one-hot类型,代表是狗)假设我们有一个数据集X,X赋值为[[0.6,0.9]],X的形状为(1,2)代表1行2列

 

实现代码如下:

import numpy as np


class SimpleNet:
    def __init__(self):
        # 确保每次随机的W都是一致的
        np.random.seed(0)
        self.W = np.random.randn(2, 3)

    # 前向传播
    def forward(self, x):
        return np.dot(x, self.W)

    def loss(self, x, y):
        # 得到预测值
        z = self.forward(x)
        # 将预测值调用softmax函数为相加之和为1的概率矩阵
        p = _softmax(z)
        loss = cross_entropy_error(p, y)
        return loss


# p为预测值 y为真值
def cross_entropy_error(p, y):
    return np.sum(-y * np.log(p))


def _softmax(x):
    if x.ndim == 2:
        # 因为x为二维函数,所以shape为(ndim,row,column)
        # axis=1:求各column的最大值
        # axis=2:求各row的最大值
        D = np.max(x, axis=1)
        # 由于是求各列的最大值,所以需要对x进行转置
        x = x.T - D  # 溢出对策
        # np.sum(a, axis=0) 表示的是将二维数组中的各个元素对应相加
        # axis =1 时, 表示的是二维数组中的各自维的列相加
        # axis =2 时, 表示的是二维数组中的各自维的行相加
        y = np.exp(x) / np.sum(np.exp(x), axis=0)
        return y.T
    D = np.max(x)
    exp_x = np.exp(x - D)
    return exp_x / np.sum(exp_x)


# 数值微分的梯度下降法
def numerical_gradient(f, x):
    h = 1e-4  # 0.0001
    # 生成与x一元形状的0矩阵
    grad = np.zeros_like(x)

    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
    while not it.finished:
        idx = it.multi_index
        tmp_val = x[idx]
        # f(x+h) 的计算
        x[idx] = float(tmp_val) + h
        fxh1 = f(x)
        # f(x-h) 的计算
        x[idx] = float(tmp_val) - h
        fxh2 = f(x)
        grad[idx] = (fxh1 - fxh2) / (2 * h)

        x[idx] = tmp_val
        it.iternext()
    return grad


#  梯度下降
def gradient_descent(f, init_x, lr=0.01, step_num=1000):
    x = init_x
    for i in range(step_num):
        grad = numerical_gradient(f, x)
        x -= lr * grad

    return x


net = SimpleNet()
print(net.W)
X = np.array([[0.6, 0.9]])
# 输入正确的类别
y = np.array([0, 0, 1])
p = net.forward(X)
print('预测值为:', p)
print('预测的类别为:', np.argmax(p))
print('损失之Loss为:', net.loss(X, y))

f = lambda w: net.loss(X, y)

dw = gradient_descent(f, net.W)  # 主要更新的是w
print(dw)

print('损失值变为:', cross_entropy_error(_softmax(np.dot(X, dw)), y))
print('预测类别为:', np.argmax(np.dot(X, dw)))

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值