1019手写数字识别

 手写识别1

import numpy as np
import struct
import os
import matplotlib.pyplot as plt

def load_labels(file):  # 加载数据
    with open(file, "rb") as f:
        data = f.read()
    return np.asanyarray(bytearray(data[8:]), dtype=np.int32)


def load_images(file):  #  加载数据
    with open(file, "rb") as f:
        data = f.read()
    magic_number, num_items, rows, cols = struct.unpack(">iiii", data[:16])
    return np.asanyarray(bytearray(data[16:]), dtype=np.uint8).reshape(num_items, -1)

class Dataset:
    def __init__(self,x,y,batch_size , shuffle = True):
        self.x = x
        self.y = y
        self.batch_size = batch_size
        self.shuffle = shuffle

    def __iter__(self):
        temp = DataLoader(self)
        return temp

    def __len__(self):
        return len(self.x)

class DataLoader:
    def __init__(self,dataset):
        self.dataset = dataset
        self.cursor = 0
        self.indexs = np.arange(len(self.dataset))
        if self.dataset.shuffle:
            np.random.shuffle(self.indexs)

    def __next__(self):

        if self.cursor >= len(self.dataset):
            raise StopIteration

        index = self.indexs[self.cursor : self.cursor + self.dataset.batch_size]
        x = self.dataset.x[index]
        y = self.dataset.y[index]

        self.cursor += self.dataset.batch_size

        return x ,y

def label_to_onehot(labels,class_num=10):
    batch_num = labels.shape[0]
    result = np.zeros((batch_num,class_num))

    for i,l in enumerate(labels):
        result[i][l] = 1
    return result

def softmax(x):
    ex = np.exp(x)
    # sum_ex = np.sum(ex,axis=1).reshape(-1,1)
    sum_ex = np.sum(ex,axis=1,keepdims=True)#这里我们要注意,其实这里保持维度是没有影响的,因为我们只对最后一个维度求和,所以这里的keepdims=True,不然我们batch·size=2的时候,就会变成1维的。
    #keepdims是保持原有的形状不变

    return ex/sum_ex


if __name__ == "__main__":
    train_data = load_images(os.path.join("..","data","train-images.idx3-ubyte")) / 255#这里需要除以255,因为数据集的像素值是0-255,我们对数据进行归一化处理
    train_label = label_to_onehot(load_labels(os.path.join("..","data","train-labels.idx1-ubyte")))

    dev_data = load_images(os.path.join("..", "data", "t10k-images.idx3-ubyte")) / 255
    dev_label = load_labels(os.path.join("..", "data", "t10k-labels.idx1-ubyte"))

    W = np.random.normal(0,1,size=(784,10))
    b = 0

    lr = 0.01
    epoch = 1000
    batch_size = 20

    dataset = Dataset(train_data,train_label,batch_size,shuffle=False)

    for e in range(epoch):
        print(f"{e}_{'*'*100}")
        for bi,(batch_data,batch_label) in enumerate(dataset):
            pre = batch_data @ W + b   # 1 * 784 @ 784 * 10 = 1 * 10
            soft_pre = softmax(pre)#这里是多元交叉熵和softmax的结合,
            #
            #归一化
            loss = -np.sum(batch_label*np.log(soft_pre)) / batch_data.shape[0]
            #多元交叉熵

            G = (soft_pre - batch_label ) / batch_data.shape[0]
            #这里是多元交叉熵和softmax的结合,我们求导的时候,要先求loss对于soft_pre的导数,再求soft_pre对pre的倒数,最后求w和b的导数
            #经过查询,我们知道loss对pre的导数就是soft_pre - batch_label,  就是经过softmax之后的结果与真实标签的差值
            delta_W = batch_data.T @ G
            delta_b = np.mean(G)#这里就是死记硬背,

            W -= lr * delta_W
            b -= lr * delta_b

            # if bi % 50 == 0 :
            #     print(loss)

        right_num = 0
        p = dev_data @ W + b#这里是预测的结果
        p = np.argmax(p,axis=1)#我们就不用softmax了,直接取最大值

        for pl,tl in zip(p,dev_label):
            if pl == tl:
              right_num+=1

        acc = right_num/len(dev_label) * 100
        print(f"acc:{acc}%")

手写识别2

我们将隐藏层变成两层,就是加一个w2

import numpy as np
import struct
import os
import matplotlib.pyplot as plt

def load_labels(file):  # 加载数据
    with open(file, "rb") as f:
        data = f.read()
    return np.asanyarray(bytearray(data[8:]), dtype=np.int32)


def load_images(file):  # 加载数据
    with open(file, "rb") as f:
        data = f.read()
    magic_number, num_items, rows, cols = struct.unpack(">iiii", data[:16])
    return np.asanyarray(bytearray(data[16:]), dtype=np.uint8).reshape(num_items, -1)

class Dataset:
    def __init__(self,x,y,batch_size , shuffle = True):
        self.x = x
        self.y = y
        self.batch_size = batch_size
        self.shuffle = shuffle

    def __iter__(self):
        temp = DataLoader(self)
        return temp

    def __len__(self):
        return len(self.x)

class DataLoader:
    def __init__(self,dataset):
        self.dataset = dataset
        self.cursor = 0

        self.indexs = np.arange(len(self.dataset))
        if self.dataset.shuffle:
            np.random.shuffle(self.indexs)

    def __next__(self):

        if self.cursor >= len(self.dataset):
            raise StopIteration

        index = self.indexs[self.cursor : self.cursor + self.dataset.batch_size]
        x = self.dataset.x[index]
        y = self.dataset.y[index]

        self.cursor += self.dataset.batch_size

        return x ,y

def label_to_onehot(labels,class_num=10):
    batch_num = labels.shape[0]
    result = np.zeros((batch_num,class_num))

    for i,l in enumerate(labels):
        result[i][l] = 1
    return result

def softmax(x):
    ex = np.exp(x)
    # sum_ex = np.sum(ex,axis=1).reshape(-1,1)
    sum_ex = np.sum(ex,axis=1,keepdims=True)
    return ex/sum_ex

def sigmoid(x):
    # x = np.clip(x,-1000,1000)
    return 1/(1+np.exp(-x))

def tanh(x):
    return 2 * sigmoid(2*x) - 1


if __name__ == "__main__":
    train_data = load_images(os.path.join("..","data","train-images.idx3-ubyte")) / 255
    train_label = label_to_onehot(load_labels(os.path.join("..","data","train-labels.idx1-ubyte")))

    dev_data = load_images(os.path.join("..", "data", "t10k-images.idx3-ubyte")) / 255
    dev_label = load_labels(os.path.join("..", "data", "t10k-labels.idx1-ubyte"))

    # b1 = 0
    # b2 = 0
    lr = 0.1
    epoch = 1000
    batch_size = 100
    hidden_size = 256
    
    W1 = np.random.normal(0,1,size=(784,hidden_size)) # 凯明初始化
    W2 = np.random.normal(0,1,size=(hidden_size,10))

    b1 = np.zeros((1,hidden_size))
    b2 = np.zeros((1,10))

    dataset = Dataset(train_data,train_label,batch_size,shuffle=True)

    for e in range(epoch):
        print(f"{e}_{'*'*100}")
        for bi,(batch_data,batch_label) in enumerate(dataset):
            hidden = batch_data @ W1 + b1   # 1 * 784 @ 784 * 10 = 1 * 10
            tanh_hid = sigmoid(hidden)
            pre = tanh_hid @ W2 + b2
            soft_pre = softmax(pre)
            loss = -np.sum(batch_label*np.log(soft_pre)) / batch_data.shape[0]

            G1 = (soft_pre - batch_label ) / batch_data.shape[0]
            delta_W2 = tanh_hid.T @ G1
            delta_th = G1 @ W2.T

            G2 = delta_th * tanh_hid * (1-tanh_hid)#在这一步,我们是想求loss对于pre的导数,其实就是loss对于tanh的导数乘上tanh对于pre的导数。
            delta_W1 = batch_data.T @ G2

            delta_b1 = np.sum(G2,axis=0,keepdims=True)
            delta_b2 = np.sum(G1,axis=0,keepdims=True)

            W1 -= lr * delta_W1
            W2 -= lr * delta_W2
            b1 -= lr * delta_b1
            b2 -= lr * delta_b2

            # if bi % 50 == 0 :
            #     print(loss)

        right_num = 0
        h = dev_data @ W1 + b1
        h = sigmoid(h)
        p = h @ W2 + b2
        p = np.argmax(p,axis=1)

        for pl,tl in zip(p,dev_label):
            if pl == tl:
              right_num+=1

        acc = right_num/len(dev_label) * 100
        print(f"acc:{acc}%")

手写识别3

没改什么

import numpy as np
import struct
import os
import matplotlib.pyplot as plt

def load_labels(file):  # 加载数据
    with open(file, "rb") as f:
        data = f.read()
    return np.asanyarray(bytearray(data[8:]), dtype=np.int32)


def load_images(file):  # 加载数据
    with open(file, "rb") as f:
        data = f.read()
    magic_number, num_items, rows, cols = struct.unpack(">iiii", data[:16])
    return np.asanyarray(bytearray(data[16:]), dtype=np.uint8).reshape(num_items, -1)

class Dataset:
    def __init__(self,x,y,batch_size , shuffle = True):
        self.x = x
        self.y = y
        self.batch_size = batch_size
        self.shuffle = shuffle

    def __iter__(self):
        temp = DataLoader(self)
        return temp

    def __len__(self):
        return len(self.x)

class DataLoader:
    def __init__(self,dataset):
        self.dataset = dataset
        self.cursor = 0

        self.indexs = np.arange(len(self.dataset))
        if self.dataset.shuffle:
            np.random.shuffle(self.indexs)

    def __next__(self):

        if self.cursor >= len(self.dataset):
            raise StopIteration

        index = self.indexs[self.cursor : self.cursor + self.dataset.batch_size]
        x = self.dataset.x[index]
        y = self.dataset.y[index]

        self.cursor += self.dataset.batch_size

        return x ,y

def label_to_onehot(labels,class_num=10):
    batch_num = labels.shape[0]
    result = np.zeros((batch_num,class_num))

    for i,l in enumerate(labels):
        result[i][l] = 1
    return result

def softmax(x):
    ex = np.exp(x)
    # sum_ex = np.sum(ex,axis=1).reshape(-1,1)
    sum_ex = np.sum(ex,axis=1,keepdims=True)
    return ex/sum_ex

def sigmoid(x):
    # x = np.clip(x,-1000,1000)
    return 1/(1+np.exp(-x))

def tanh(x):
    return 2 * sigmoid(2*x) - 1


if __name__ == "__main__":
    train_data = load_images(os.path.join("..","data","train-images.idx3-ubyte")) / 255
    train_label = label_to_onehot(load_labels(os.path.join("..","data","train-labels.idx1-ubyte")))

    dev_data = load_images(os.path.join("..", "data", "t10k-images.idx3-ubyte")) / 255
    dev_label = load_labels(os.path.join("..", "data", "t10k-labels.idx1-ubyte"))

    # b1 = 0
    # b2 = 0
    lr = 0.1
    epoch = 1000
    batch_size = 100
    hidden_size = 256
    
    W1 = np.random.normal(0,1,size=(784,hidden_size)) # 凯明初始化
    W2 = np.random.normal(0,1,size=(hidden_size,10))

    b1 = np.zeros((1,hidden_size))
    b2 = np.zeros((1,10))

    dataset = Dataset(train_data,train_label,batch_size,shuffle=True)

    for e in range(epoch):
        print(f"{e}_{'*'*100}")
        for bi,(batch_data,batch_label) in enumerate(dataset):
            hidden = batch_data @ W1 + b1   # 1 * 784 @ 784 * 10 = 1 * 10
            tanh_hid = sigmoid(hidden)
            pre = tanh_hid @ W2 + b2
            soft_pre = softmax(pre)
            loss = -np.sum(batch_label*np.log(soft_pre)) / batch_data.shape[0]

            G2 = (soft_pre - batch_label ) / batch_data.shape[0]
            delta_W2 = tanh_hid.T @ G2
            delta_th = G2 @ W2.T

            G1 = delta_th * tanh_hid * (1-tanh_hid)
            delta_W1 = batch_data.T @ G1

            delta_b1 = np.sum(G1,axis=0,keepdims=True)
            delta_b2 = np.sum(G2,axis=0,keepdims=True)

            W1 -= lr * delta_W1
            W2 -= lr * delta_W2
            b1 -= lr * delta_b1
            b2 -= lr * delta_b2

            # if bi % 50 == 0 :
            #     print(loss)

        right_num = 0
        h = dev_data @ W1 + b1
        h = sigmoid(h)
        p = h @ W2 + b2
        p = np.argmax(p,axis=1)
        acc = sum(p == dev_label) / len(dev_label) * 100#p == dev_label  里面的答案都是fales和true,我们将其sum,false的个数就是0,true的个数就是1,最后除以总个数,乘以100就是正确率
        print(f"acc:{acc}%")

手写识别4

将封装了linner层

在里面完成求值求导的操作

import numpy as np
import struct
import os
import matplotlib.pyplot as plt

def load_labels(file):  # 加载数据
    with open(file, "rb") as f:
        data = f.read()
    return np.asanyarray(bytearray(data[8:]), dtype=np.int32)


def load_images(file):  # 加载数据
    with open(file, "rb") as f:
        data = f.read()
    magic_number, num_items, rows, cols = struct.unpack(">iiii", data[:16])
    return np.asanyarray(bytearray(data[16:]), dtype=np.uint8).reshape(num_items, -1)

class Dataset:
    def __init__(self,x,y,batch_size , shuffle = True):
        self.x = x
        self.y = y
        self.batch_size = batch_size
        self.shuffle = shuffle

    def __iter__(self):
        temp = DataLoader(self)
        return temp

    def __len__(self):
        return len(self.x)

class DataLoader:
    def __init__(self,dataset):
        self.dataset = dataset
        self.cursor = 0

        self.indexs = np.arange(len(self.dataset))
        if self.dataset.shuffle:
            np.random.shuffle(self.indexs)

    def __next__(self):

        if self.cursor >= len(self.dataset):
            raise StopIteration

        index = self.indexs[self.cursor : self.cursor + self.dataset.batch_size]
        x = self.dataset.x[index]
        y = self.dataset.y[index]

        self.cursor += self.dataset.batch_size

        return x ,y

def label_to_onehot(labels,class_num=10):
    batch_num = labels.shape[0]
    result = np.zeros((batch_num,class_num))

    for i,l in enumerate(labels):
        result[i][l] = 1
    return result

def softmax(x):
    ex = np.exp(x)
    # sum_ex = np.sum(ex,axis=1).reshape(-1,1)
    sum_ex = np.sum(ex,axis=1,keepdims=True)
    return ex/sum_ex

def sigmoid(x):
    # x = np.clip(x,-1000,1000)
    return 1/(1+np.exp(-x))

def tanh(x):
    return 2 * sigmoid(2*x) - 1

class NN_layer:
    pass


class Linear(NN_layer):
    def __init__(self,in_feature,out_feature):
        self.W = np.random.normal(0,1,size=(in_feature,out_feature))
        self.b = np.zeros((1,out_feature))

    def forward(self,x):
        result = x @ self.W + self.b
        self.A = x
        return result

    def backward(self,G):
        delta_W = self.A.T @ G
        delta_b = np.sum(G,axis=0,keepdims=True)

        self.W -= delta_W * lr
        self.b -= delta_b * lr

        return G @ self.W.T


if __name__ == "__main__":
    train_data = load_images(os.path.join("..","data","train-images.idx3-ubyte")) / 255
    train_label = label_to_onehot(load_labels(os.path.join("..","data","train-labels.idx1-ubyte")))

    dev_data = load_images(os.path.join("..", "data", "t10k-images.idx3-ubyte")) / 255
    dev_label = load_labels(os.path.join("..", "data", "t10k-labels.idx1-ubyte"))

    # b1 = 0
    # b2 = 0
    lr = 0.1
    epoch = 1000
    batch_size = 100
    hidden_size = 256
    
    linear1 = Linear(784,hidden_size)
    linear2 = Linear(hidden_size,10)

    dataset = Dataset(train_data,train_label,batch_size,shuffle=True)

    for e in range(epoch):
        print(f"{e}_{'*'*100}")
        for bi,(batch_data,batch_label) in enumerate(dataset):
            hidden = linear1.forward(batch_data)
            tanh_hid = sigmoid(hidden)
            pre = linear2.forward(tanh_hid)
            soft_pre = softmax(pre)
            loss = -np.sum(batch_label*np.log(soft_pre)) / batch_data.shape[0]

            G2 = (soft_pre - batch_label ) / batch_data.shape[0]
            delta_th = linear2.backward(G2)

            G1 = delta_th * tanh_hid * (1-tanh_hid)
            linear1.backward(G1)

        right_num = 0
        h = linear1.forward(dev_data)
        h = sigmoid(h)
        p = linear2.forward(h)
        p = np.argmax(p,axis=1)
        acc = sum(p == dev_label) / len(dev_label) * 100
        print(f"acc:{acc}%")

手写识别5

添加了sigmoid层

在里面完成求值求导的操作

import numpy as np
import struct
import os
import matplotlib.pyplot as plt

def load_labels(file):  # 加载数据
    with open(file, "rb") as f:
        data = f.read()
    return np.asanyarray(bytearray(data[8:]),
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值