机器学习笔记

开始机器学习

  • 机器学习的hello word–手写数字识别
  • 语言–python
  • 环境/平台–colab

colab介绍

谷歌免费的GPU资源,但是要科学上网,你有谷歌账号就行,具体使用方法自行百度。

cd需要加%才能使用
其他的加!使用
例如:

%cd drive/MyDrive/Colab\ Notebooks
!pwd

开始吧

1.导入一些库

import numpy as np  #针对数组运算提供大量的数学函数库
import scipy.special #字符串切片用
import matplotlib.pyplot #画图

2.神经网络的结构

class class neuralNetwork:
	#初始化函数 
	def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
	#训练函数
	def train(self,inputs_list,targets_list):
	#预测函数/查询函数 //喜欢怎么叫就怎么叫吧
	def query(self,inputs_list):

3.函数的实现

  • 3.1初始化函数:
    因为是第一次,所以用一个非常简单的神经网络,只有三层,输入层1,隐藏层1,输出层1。
    所以初始化时必须先定义一下这些层,同时需要定义学习率(learning rate),激活函数(activation function)。当然,还要初试化权重。
def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
      #neural number 每一层神经元数量
      self.inodes = inputnodes
      self.hnodes = hiddennodes
      self.onodes = outputnodes
      #learning rate 学习率 //我的理解是每次更新权重参数的步长
      self.lr = learningrate
      #weights 权重
      self.wih=(np.random.rand(self.hnodes,self.inodes)-0.5)
      self.who=(np.random.rand(self.onodes,self.hnodes)-0.5)
      #activation function 激活函数 sigmoid
      self.activation_function = lambda x:scipy.special.expit(x)
  • 3.2训练函数:
    优化方法是SGD(随机梯度下降法),计算梯度利用了反向传播法(直接从前往后算梯度非常复杂,而从后向前则简单很多 就是链式法则//具体理解请自行搜索)。
def train(self,inputs_list,targets_list):
    #将输入转为二维矩阵
    inputs = np.array(inputs_list,ndmin=2).T #输入的28*28个数
    targets = np.array(targets_list,ndmin=2).T#标签 即正确的数
    #前向传播
    hidden_inputs = np.dot(self.wih,inputs)
    hidden_outputs=self.activation_function(hidden_inputs)
    final_inputs=np.dot(self.who,hidden_outputs)
    final_outputs=self.activation_function(final_inputs)
    #反向传播 更新权重
    output_errors=targets - final_outputs
    hidden_errors=np.dot(self.who.T,output_errors)
    self.who += self.lr*np.dot((output_errors*final_outputs*(1.0-final_outputs)),np.transpose(hidden_outputs))
    self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0-hidden_outputs)),np.transpose(inputs))
    pass
  • 3.3查询函数:
    这就很简单了,将数据输入,根据权重直接计算结果。
def query(self,inputs_list):
    #将输入转为二维矩阵
    inputs = np.array(inputs_list,ndmin=2).T
    #print(inputs)
    #输入乘以第一层权重
    hidden_inputs = np.dot(self.wih,inputs)
    #通过激活函数输出
    hidden_outputs=self.activation_function(hidden_inputs)
    #最后一层,和前面一样
    final_inputs=np.dot(self.who,hidden_outputs)
    final_outputs=self.activation_function(final_inputs)
    return final_outputs
  • 3.4整体神经网络代码:
import numpy as np
import scipy.special
import matplotlib.pyplot

class neuralNetwork:
  def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
      self.inodes = inputnodes
      self.hnodes = hiddennodes
      self.onodes = outputnodes
      self.lr = learningrate
      #weights
      self.wih=(np.random.rand(self.hnodes,self.inodes)-0.5)
      self.who=(np.random.rand(self.onodes,self.hnodes)-0.5)
      #activation function
      self.activation_function = lambda x:scipy.special.expit(x)
      pass
  def train(self,inputs_list,targets_list):
    #将输入转为二维矩阵
    inputs = np.array(inputs_list,ndmin=2).T
    targets = np.array(targets_list,ndmin=2).T
    hidden_inputs = np.dot(self.wih,inputs)
    hidden_outputs=self.activation_function(hidden_inputs)
    final_inputs=np.dot(self.who,hidden_outputs)
    final_outputs=self.activation_function(final_inputs)
    output_errors=targets - final_outputs
    hidden_errors=np.dot(self.who.T,output_errors)
    self.who += self.lr*np.dot((output_errors*final_outputs*(1.0-final_outputs)),np.transpose(hidden_outputs))
    self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0-hidden_outputs)),np.transpose(inputs))
    pass
  def query(self,inputs_list):
    #将输入转为二维矩阵
    inputs = np.array(inputs_list,ndmin=2).T
    #print(inputs)
    #输入乘以第一层权重
    hidden_inputs = np.dot(self.wih,inputs)
    #通过激活函数输出
    hidden_outputs=self.activation_function(hidden_inputs)
    #最后一层,和前面一样
    final_inputs=np.dot(self.who,hidden_outputs)
    final_outputs=self.activation_function(final_inputs)
    return final_outputs

    pass

4.跑数据训练它:
经典的mnist数据集,直接跑,也不管小批量了好吧,第一次能成就行,直接整个数据跑。7个epoch用时7-8分钟。

#神经元数量
input_nodes = 784
hidden_nodes = 200
output_nodes = 10
#学习率
lr=0.2
#初始化神经网络
n=neuralNetwork(input_nodes,hidden_nodes,output_nodes,lr)
#打开并读取数据集
training_data_file= open("mnist_train.csv",'r')
training_data_list = training_data_file.readlines()
training_data_file.close
#跑7个epoch
for e in range(7):
  #每一笔数据取出后将标签拿出来,其他的传给训练函数
  for record in training_data_list:
    all_values = record.split(',')
    inputs=(np.asfarray(all_values[1:])/255.0 *0.99)+0.01
    targets = np.zeros(output_nodes)+0.01
    targets[int(all_values[0])]=0.99
    n.train(inputs,targets)
    pass
  pass

5.训练完成后进行测试:

#记录正确与否
scorecard = []
#打开并读取数据
test_data_file = open("mnist_test.csv",'r')
test_data_list = test_data_file.readlines()
test_data_file.close()
#测试
for re in test_data_list:
  all_values = re.split(',')
  #获取正确的标签
  correct_lable = int (all_values[0])
  #print(correct_lable,"correct lable")
  inputs = (np.asfarray(all_values[1:])/255.0*0.99)+0.01
  outputs = n.query(inputs)
  lable = np.argmax(outputs)
 # print(lable,"network's answer")
 #正确就写1,否写0
  if (lable == correct_lable):
    scorecard.append(1)
  else:
    scorecard.append(0)
scorecard_array = np.asarray(scorecard)
#计算正确率
print("正确率:",scorecard_array.sum()/scorecard_array.size*100,'%')

6.结果还不错,96了。当然,我这是作弊的,学习率没有自己试,而是借鉴了前辈们的,哈哈哈。
跑7个epoch,学习率0.2
感谢观看,后续学习继续更新,奥利给,xdm!

2021/10/22更新

padans:

在复现高斯朴素贝叶斯模型时:

def fit(self, X, y):
        classes = y[y.columns[0]].unique() #有几类需要划分
        class_count = y[y.columns[0]].value_counts() #每一类的总个数
        # 类先验概率
        class_prior = class_count / len(y) #P(0) P(1) p(2)
        # 计算类条件概率
        prior = dict()
        for col in X.columns:
            for j in classes:
                mstd = []
                data_x_y = X[(y == j).values][col] #pandas数据格式 共用一个索引 所以这样筛选 且自动遍历所有的行 
                #print("(y == j).values:",(y == j).values)
               # print("data_x_y:",data_x_y)
                m_x_y = np.mean(data_x_y) #平均值
                print(m_x_y)
                mstd.append(m_x_y)
                std_x_y = np.std(data_x_y)#标准差
                mstd.append(std_x_y)
                prior[(col, j)] = mstd
                print("prior",prior)

        return classes, class_prior, prior

X:

y:

之前没有学过pandas,看不懂其中:

data_x_y = X[(y == j).values][col]

为什么可以在X中用y来筛选?为什么不需要遍历行向量?
Pandas DataFrames :
在这里插入图片描述
重点 :共用一个索引
他们可以不一起建立 ,之后建立的series也是共用的。所以可以用y来筛选X中的数据
自动返回一个series,不用再写遍历行的循环。

2021/11/2更新

pytorch的学习(B站up我是土堆的视频)

1.1对数据集的读取:

数据集介绍,图片放在对应的文件夹里,标签就是文件夹名称
在这里插入图片描述
导入dataset

from torch.utils.data import Dataset 

在这里插入图片描述
详细请参考pytorch数据加载
案例:

from torch.utils.data import Dataset
import os
from PIL import Image


class MyData(Dataset):

    def __init__(self, root_dir , label_dir):
        self.root_dir = root_dir
        self.label_dir = label_dir
        self.path = os.path.join(root_dir, label_dir)
        self.img_path_list = os.listdir(self.path)

    def __getitem__(self, idx):
        img_name = self.img_path_list[idx]
        img_item_path = os.path.join(self.path, img_name)
        # img = Image.open(img_item_path)
        # label = self.lable_dir
        return Image.open(img_item_path), self.label_dir

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


root_dir = "dataset/train"
ants_dir = "ants"
bees_dir = "bees"
ants_dataset = MyData(root_dir, ants_dir)
bees_dataset = MyData(root_dir, bees_dir)

1.2 tensorboard 使用(打印los图和训练的图)

from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image


writer = SummaryWriter("logs")
image_path = "dataset/train/ants/6240329_72c01e663e.jpg"
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)
writer.add_image("test", img_array, 2, dataformats='HWC')
for i in range(100):
    writer.add_scalar("y=x", i, i)
writer.close()

# how to open log files
# use Command Prompt with code tensorboard --logdir=logs --port=6007


12/11/5更新

1.3 transforms

对数据进行处理 ,比如将PIL的Image转为tensor(张量)-Totensor
使用方法:

tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
normlize
norm = transforms.Normalize([3, 5, 7], [1, 4, 9])
img_norm = norm(img_tensor)
resize
resize = transforms.Resize(200)
# img PIL -> img_resize PIL
img_resize = resize(img)
# img_resize PIL->img_resize1 tensor
img_resize1 = totensor(img_resize)
compose
# img -> resize -> tensor -> writer
compose = transforms.Compose([transforms.Resize(100), transforms.ToTensor()])
img_compose_resize = compose(img)
writer.add_image("compose", img_compose_resize, 0)
2.1 nn.module

自己写的网络继承nn.module 比如下面 测试maxpooling (从nn导入)


import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("./CIFDataset", train=False, transform=torchvision.transforms.ToTensor())
dataloader = DataLoader(dataset, batch_size=64)

writer = SummaryWriter("logs")


class MyTextModule(nn.Module):

    def __init__(self):
        super(MyTextModule, self).__init__()
        # self.conv1 = Conv2d(in_channels=3, out_channels=3, kernel_size=3, stride=1, padding=0)
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=False)

    def forward(self, input):
        # Coutput = self.conv1(x)
        output = self.maxpool1(input)

        return output


myTextModule = MyTextModule()
step = 0
for data in dataloader:
    imgs, targets = data
    writer.add_images("imput", imgs, step)
    output = myTextModule(imgs)
    # output1 = torch.reshape(output, (-1, 3, 32, 32))
    writer.add_images("output", output, step)
    step += 1
writer.close()



2.2 网络训练的保存和加载

就是你训练后权重怎么保存和使用 总不能每次预测都要重新训练吧 哈哈哈
两种保存方式

import torch
import torchvision


vgg16 = torchvision.models.vgg16(pretrained=False)
# 保存方式1 模型结构加参数
torch.save(vgg16, "vgg16_method1.pth")
# 保存方式2 模型参数(官方推荐)
torch.save(vgg16.state_dict(), "vgg16_method2.pth")

两种读取方式

import  torch
import torchvision.models
#方法一获取
model = torch.load("vgg16_method1.pth")
print(model)

# 方法二获取数据
vgg16 = torchvision.models.vgg16(pretrained=False)
vgg16.load_state_dict(torch.load("vgg16_method2.pth"))
model2 = torch.load("vgg16_method2.pth")
print(vgg16)

vgg16_method2.pth 是在保存时自己设置的名字 保存在同级目录下 若想上一级就是"./vgg16_method2.pth"

2.3 自己写一个网络

使用pytorch提供的数据集 cifar10 ,网络结构网上随便找的简单的网络
在这里插入图片描述
注释是没有使用Sequential,相当于没有打包在一起,Sequential可以将网络层打包在一起

from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential


class MyFirstNet(nn.Module):
    def __init__(self):
        super(MyFirstNet, self).__init__()
        # self.conv1 = Conv2d(3, 32, 5, padding=2)
        # self.maxpool1 = MaxPool2d(2)
        # self.conv2 = Conv2d(32, 32, 5, padding=2)
        # self.maxpool2 = MaxPool2d(2)
        # self.conv3 = Conv2d(32, 64, 5, padding=2)
        # self.maxpool3 = MaxPool2d(2)
        # self.flatten = Flatten()
        # self.linear1 = Linear(1024, 64)
        # self.linear2 = Linear(64, 10)

        self.model1 = Sequential(
            Conv2d(3, 32, (5, 5), padding=2),
            MaxPool2d(2),
            Conv2d(32, 32, (5, 5), padding=2),
            MaxPool2d(2),
            Conv2d(32, 64, (5, 5), padding=2),
            MaxPool2d(2),
            Flatten(),
            Linear(1024, 64),
            Linear(64, 10)
        )

    def forward(self, x):
        # x = self.conv1(x)
        # x = self.maxpool1(x)
        # x = self.conv2(x)
        # x = self.maxpool2(x)
        # x = self.conv3(x)
        # x = self.maxpool3(x)
        # x = self.flatten(x)
        # x = self.linear1(x)
        # x = self.linear2(x)
        x = self.model1(x)
        return x

2.4 训练网络

网络结构从之前的写的网络中导入from FirstNet import MyFirstNet

import time

import torch.optim
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

from FirstNet import MyFirstNet

# 导入数据
train_data = torchvision.datasets.CIFAR10("./CIFDataset", train=True, transform=torchvision.transforms.ToTensor())
test_data = torchvision.datasets.CIFAR10("./CIFDataset", train=False, transform=torchvision.transforms.ToTensor())

# train_data_size = len(train_data)
# test_data_size = len(test_data)
# print(train_data_size,test_data_size)
# 数据加载
train_dataloader = DataLoader(train_data, 64)
test_dataloader = DataLoader(test_data, 64)

# 创建网络模型
mynet = torch.load("torch_10.pth")  # 使用上次训练完之后的参数 
mynet = mynet.cuda()
# 损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.cuda()
# 优化器
lenarning_rate = 1e-5
optimizer = torch.optim.SGD(mynet.parameters(), lr=lenarning_rate)

# 设置训练网络
total_train_step = 0
total_test_step = 0
# 训练轮数
epoch = 10
# 可视化
writer = SummaryWriter("./trainLos")

# 开始训练
start_time = time.time()
for i in range(epoch):
    print("---第{}轮训练:---".format(i + 1))
    mynet.train()
    for imgS, targets in train_dataloader:
        imgS = imgS.cuda()
        targets = targets.cuda()
        output = mynet(imgS)
        loss = loss_fn(output, targets)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        total_train_step += 1
        if total_train_step % 100 == 0:
            end_time = time.time()
            print(end_time - start_time)
            print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))
            writer.add_scalar("train_loss", loss.item(), total_train_step)
    # 测试步骤开始
    mynet.eval()
    total_accuracy = 0
    total_test_loss = 0
    with torch.no_grad():
        for imgS, targetS in test_dataloader:
            imgS = imgS.cuda()
            targetS = targetS.cuda()
            output = mynet(imgS)
            loss = loss_fn(output, targetS)
            total_test_loss += loss.item()
            accuracy = (output.argmax(1) == targetS).sum()
            total_accuracy += accuracy
    print("整体测试集误差{}".format(total_test_loss))
    print("整体测试集正确率{}".format(total_accuracy/len(test_data)))
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    writer.add_scalar("test_accuracy", total_accuracy/len(test_data), total_test_step)
    total_test_step += 1

    # 保存参数
    torch.save(mynet, "torch_{}.pth".format(epoch))
    print("模型已保存")

writer.close()


训练几次后的效果,初始Learnningrate=0.01 第一次10个epoch跑完之后,将learnningrate调小10倍 在跑完10个epoch后再继续调小 下图是结果 正确率到0.69基本上就是这个的极限了
在这里插入图片描述

2.5 测试网络

用一张没见过的图片进性预测

import torch
import torchvision.transforms
from PIL import Image

img_path = "./imgs/dog.png"
image = Image.open(img_path)
image = image.convert('RGB')

transfrom = torchvision.transforms.Compose([torchvision.transforms.Resize((32, 32)),
                                            torchvision.transforms.ToTensor()])
image = transfrom(image)
model = torch.load("torch_10.pth", map_location=torch.device('cpu'))
print(model)
image = torch.reshape(image, (1, 3, 32, 32))
model.eval()
with torch.no_grad():
    output = model(image)

    print(output)
    print(output.argmax(1))

测试了2张图片都对了 正确率接近70%也还可以了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值