ResNet18(Pokemon)-(拨乱返正版)-Pytorch

深度学习之QLoRA原理详解及Pytorch实现 【代码】深度学习之QLoRA原理详解及Pytorch实现。 阅读详情

ResNet18-Pokemon分类项目:

1.ResNet18简介

深度学习发展到现在已经取得了非常引人注目的成果,那么在处于世界认知前沿的大佬们开始担忧未来人工智能对人类的反噬,这种担忧是具有一定前瞻性的,但是解放劳动力是科技发展的不断追求。

从一开始的LeNet5非常简单的网络模型到现在GoogLeNet(也叫谷歌LeNet,由谷歌的人工智能团队开发,为了向LeNet5致敬,取名GoogLeNet)达到了22层,人们一直在探索加深网路层数是不是可以提高model的performance,事实并不是这样的,实际上大多数网络模型发现在网络层数超过22层的时候,其整体的运算效率和performance会下降很多,也就是退化现象(Degradation),也就证明了并不是一味的加深网络层数提高网络复杂度就可以相应提高网络的performance。

后来微软亚洲研究院的何恺明等人提出了ResNet模型,其想法可以说是非常简单,就是引入残差模块,说的简单一点就是在输入和输出之间加了一条shortcut,也就是我的网络模型既可以走conv层我也可以通过shortcut直接到输出层:示意图

ResNet-basic block
那么每一个basic-block包含2个conv层和一个short-cut,那么在搭建ResNet18的时候每个residence-block会包含2个basic-block,按照ResNet18的网络结构说明可得上述说法。如图:
ResNet网络结构说明
从这个说明表中可以得到ResNet18一共是需要4个Residence Block每一个Block包含两个basic-block,而每一个basic-block包含两个conv层(这里就不算activation、batch Normalization、maxpool或者avgpool等)也就是说Residence的conv层一共有: 2 × 2 × 4 = 16 2\times2\times4=16 2×2×4=16层,再加上一开始的输入层的conv1(用来size-adjusting),最后包含一个fully-connection(fc层)一共: 16 + 1 + 1 = 18 16+1+1=18 16+1+1=18层:如下图:
ResNet18结构图
接下来到了拨乱返正的时候了,现在流传的很多关于ResNet18做Pokemon分类用来深度学习入门的示例,但是事实上他们搭建的网络根本就不是ResNet18,因为他们搭建网络层数只有10层,其错误在于:他们没有注意到每一个Residence Block需要包含两个相同的basic-block, 在他们的代码中很好的写出来了basic-block:两个conv,一个shortcut,但在搭建网络的时候直接把basic-bock当成了Residence Block,搭建了一个只有4个basic-block组成的mini-resnet,而这个mini-resnet根本就不会是18层,而是10层(譬如:这几个:
https://blog.youkuaiyun.com/weixin_51182518/article/details/113547994
https://blog.youkuaiyun.com/weixin_41391619/article/details/105068590
https://www.freesion.com/article/39581512405/等
)当然还有都是一抄百抄,结果发现抄错了!哈哈。

下面拨乱返正版开始!

2.自定义Pokemon数据集

Pytorch自定义数据集需要继承自pytorch的Dataset,下面的自定义数据集模式适合于:标准两级目录:即文件名为label,文件内容为对应该label下的data:且python的project和data在同一个root目录下

import torch
import os, glob
import random, csv
import torchvision
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from PIL import Image

# 自定义数据集

class Pokemon(Dataset):

    def __init__(self, root, resize, mode):   # root is the data_path, resize is the input imgsize of your nueral-net
        super(Pokemon,self).__init__()

        self.root = root   # 路径
        self.resize = resize  # 数据尺寸
        self.name2label = {}  # "squencial":0 加载本目录下的文件,文件名以各自的label命名,谁先加载进来谁标记为0
        for name in sorted(os.listdir((os.path.join(root)))):  # 将root根目录下的所有文件名遍历一下
            if not os.path.isdir(os.path.join(root, name)):  # lsitdir 可能返回的顺序不固定 因此加sorted可以让顺序固定下来
                continue

            self.name2label[name] = len(self.name2label.keys())
        # print(self.name2label)

        self.images, self.labels = self.load_csv('images.csv')

        # img crop
        if mode=='train':  # 60%
            self.images = self.images[:int(0.6*len(self.images))]
            self.labels = self.labels[:int(0.6*len(self.labels))]

        elif mode == 'val': # 20%
            self.images = self.images[int(0.6 * len(self.images)):int(0.8 * len(self.images))]
            self.labels = self.labels[int(0.6 * len(self.labels)):int(0.8 * len(self.labels))]

        else: # test_set 80%-100%
            self.images = self.images[int(0.8 * len(self.images)):]
            self.labels = self.labels[int(0.8 * len(self.labels)):]


    # image, label

    def load_csv(self, filename):

        if not os.path.exists(os.path.join(self.root, filename)): # 如果根目录下不存在该CSV文件 就遍历创建
            # 如果存在直接读取
            images = []
            for name in self.name2label.keys():    # 将所有的图片加载到images中去,图片所对应的类别用路径进行区分
                images += glob.glob(os.path.join(self.root, name, '*.png'))
                images += glob.glob(os.path.join(self.root, name, '*.jpg'))
                images += glob.glob(os.path.join(self.root, name, '*.jpeg'))
                # images += glob.glob(os.path.join(self.root, name, '*.tiff'))

            # 1167 pokemon\\bulbasaur\\00000000.png
            print(len(images), images)

            random.shuffle(images)
            with open(os.path.join(self.root, filename), mode='w', newline='') as f:
                writer = csv.writer(f)
                for img in images:
                    name = img.split(os.sep)[-2]  #pokemon[-3]\\bulbasaur [-2]\\00000000.png [-1]
                    label = self.name2label[name]
                    writer.writerow([img, label])
                print('written into csv file:', filename)

        # read from csv file
        images, labels = [], []
        with open(os.path.join(self.root, filename)) as f:
            reader = csv.reader(f)
            for row in reader:

                img, label = row          # 因为CSV文件保存的时候是将路径喝标签同时写入一行,路径与标签之间用逗号隔开,所以
                label = int(label)        # img, label = row, 得到的是img赋值为路径,label赋值为标签
                images.append(img)
                labels.append(label)

        assert len(images) == len(labels)
        return images, labels




    def __len__(self):
        #return len(self.samples)
        return len(self.images)


    def denormalize(self, x_hat):
        mean = [0.485, 0.456, 0.406]
        std = [0.229, 0.224, 0.225]
        #x_hat = (x-mean)/std  标准化 放缩到均值为0 标准差为1 mu=0 sigma = 1

        mean = torch.tensor(mean).unsqueeze(1).unsqueeze(1)
        std = torch.tensor(std).unsqueeze(1).unsqueeze(1)
        x = x_hat * std + mean

        return x

    def __getitem__(self, idx): # 获得当前项
        # idx~[0~len(images)]
        # return self.samples[idx]
        # self.images 保存了所有图片的路径信息, self.labels 保存了所有图片的label信息
        img, label = self.images[idx], self.labels[idx]
        tf = transforms.Compose([
            lambda x:Image.open(x).convert('RGB'), # string path => image data 将图像路径转为实际图像
            transforms.Resize((int(self.resize*1.25), int(self.resize*1.25))),
            transforms.RandomRotation(15),  # 如果rotate的角度过大的话可能导致网络不收敛
            transforms.CenterCrop(self.resize), # 中心裁剪 让旋转之后的图片不至于用黑色填充
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                 std=[0.229, 0.224, 0.225])

        ])
        img = tf(img)
        label = torch.tensor(label)

        return img, label



def main():
    import visdom
    import time
    viz = visdom.Visdom()
    db = Pokemon('pokemon', 224, 'train')


    x, y = next(iter(db))
    print('sample:', x.shape, y.shape, 'dsada', y)
    viz.image(db.denormalize(x), win='sample_x', opts = dict(title='sample_x'))
    loader = DataLoader(db, batch_size=32, shuffle=True)
    # n = 0
    for x, y in loader:
        # n += 1
        viz.images(db.denormalize(x), nrow=8, win='batch', opts=dict(title='batch'))
        viz.text(str(y.numpy()), win='label', opts=dict(title='batch-y'))  # y.numpy(), tensor to numpy
        # if n > 1:
        #     break
        time.sleep(10)

if __name__=='__main__':
    main()

3.搭建ResNet18

搭建ResNet18需要先搞清楚ResNet18到底是什么样的一个网络结构,参考目录1,一共4个Residence Block每一个包含两个basic-block。
这里定义了basic-block

import torch
import torch.nn as nn
import torch.nn.functional as F

#定义残差块ResBlock
class ResBlock(nn.Module):
    def __init__(self, inchannel, outchannel, stride=1):
        super(ResBlock, self).__init__()
        #这里定义了残差块内连续的2个卷积层
        self.left = nn.Sequential(
            nn.Conv2d(inchannel, outchannel, kernel_size=3, stride=stride, padding=1, bias=False),
            nn.BatchNorm2d(outchannel),
            nn.ReLU(inplace=True),
            nn.Conv2d(outchannel, outchannel, kernel_size=3, stride=1, padding=1, bias=False),
            nn.BatchNorm2d(outchannel)
        )
        self.shortcut = nn.Sequential()
        if stride != 1 or inchannel != outchannel:
            #shortcut,这里为了跟2个卷积层的结果结构一致,要做处理
            self.shortcut = nn.Sequential(
                nn.Conv2d(inchannel, outchannel, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(outchannel)
            )
            
    def forward(self, x):
        out = self.left(x)
        #将2个卷积层的输出跟处理过的x相加,实现ResNet的基本结构
        out = out + self.shortcut(x)
        out = F.relu(out)
        
        return out

接着我们搭建自己的ResNet18:

class ResNet18(nn.Module):
    def __init__(self, ResBlock, num_classes):
        super(ResNet18, self).__init__()
        self.inchannel = 64
        self.conv1 = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False),
            nn.BatchNorm2d(64),
            nn.ReLU()
        )
        self.layer1 = self.make_layer(ResBlock, 64, 2, stride=1)
        self.layer2 = self.make_layer(ResBlock, 128, 2, stride=2)
        self.layer3 = self.make_layer(ResBlock, 256, 2, stride=2)
        self.layer4 = self.make_layer(ResBlock, 512, 2, stride=2)
        self.fc = nn.Linear(512, num_classes)

    # 这个函数主要是用来,重复同一个残差块
    def make_layer(self, block, channels, num_blocks, stride):
        strides = [stride] + [1] * (num_blocks - 1)
        layers = []
        for stride in strides:
            layers.append(block(self.inchannel, channels, stride))
            self.inchannel = channels
        return nn.Sequential(*layers)

    def forward(self, x):
        # 在这里,整个ResNet18的结构就很清晰了
        out = self.conv1(x)
        out = self.layer1(out)
        out = self.layer2(out)
        out = self.layer3(out)
        out = self.layer4(out)
        out = F.avg_pool2d(out, 4)
        out = out.view(out.size(0), -1)
        out = self.fc(out)
        return out

训练模型用来识别Pokemon:


import torch
from torch import optim, nn
import visdom
import torchvision
from torch.utils.data import DataLoader

from manualOwnDataSet import Pokemon   # 导入自定义的数据集加载
from ResNet18_basicBlock import ResNet18 , ResBlock

batchsz = 32  # batchsize
lr = 1e-3     # learning rate
epochs = 10   # training epochs

device = torch.device('cuda') # GPU
torch.manual_seed(1234)  # random seeds

train_db = Pokemon('pokemon', 224, 'train')  # 实例化Pokemon数据类 train
val_db = Pokemon('pokemon', 224, 'val')      # 实例化Pokemon 数据集 val
test_db = Pokemon('pokemon', 224, 'test')    # 实例化Pokemon 数据集 test

train_loader = DataLoader(train_db, batch_size=batchsz, shuffle='True',  # Pytorch DataLoader加载训练数据
                          num_workers=4)
val_loader = DataLoader(val_db, batch_size=batchsz, num_workers=4)   # Pytorch DataLoader加载验证数据
test_loader = DataLoader(val_db, batch_size=batchsz, num_workers=4)  # Pytorch DataLoader加载测试数据


def evaluate(model, loader):
    correct = 0
    total = len(loader.dataset)
    for x, y in loader:
        x, y = x.to(device), y.to(device)
        with torch.no_grad():
            logits = model(x)
            pred = logits.argmax(dim=1)  # 概率最大值所在的位置
        correct += torch.eq(pred, y).sum().float().item()
    return correct / total


def main():
    model = ResNet18(ResBlock, 5).to(device)   # 创建网络模型
    optimizer = optim.Adam(model.parameters(), lr=lr)  # 创建一个优化器 如果没有特殊要求一般都是用Adam
    criteon = nn.CrossEntropyLoss()   # loss

    best_acc, best_epoch = 0, 0

    for epoch in range(epochs):  # training logicals
        for step, (x, y) in enumerate(train_loader):

            # x:[b,3,224,224],y:[b]
            x, y = x.to(device), y.to(device) # 数据加载到GPU cuda
            logits = model(x)   # 模型的输出
            loss = criteon(logits, y)

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        if epoch % 2 ==0:
            val_acc = evaluate(model, val_loader)
            if val_acc > best_acc:
                best_epoch = epoch
                best_acc = val_acc

                torch.save(model.state_dict(), 'best.mdl') # 保存模型 文件后缀无所谓

    print('best_acc:', best_acc, 'best_epoch:', best_epoch)

    model.load_state_dict(torch.load('best.mdl'))
    print('loaded from ckpt!')

    test_acc = evaluate(model, test_loader)
    print('test_acc:',test_acc)




if __name__=='__main__':
    main()

4. 训练结果

在这里插入图片描述
准确率达到90%,测试准确率也为89.3%,基本可以!

5.参考

https://debuggercafe.com/implementing-resnet18-in-pytorch-from-scratch/

PyTorch、CPU、GPU 与 CUDA 深度解析:一次张量加法背后的四层世界 本文厘清PyTorch、CPU、GPU与CUDA的层级关系:PyTorch是编程接口,CPU负责控制与调度,CUDA是让CPU指挥GPU的并行编程平台,GPU则是实际执行计算的加速器。四者非并列,而是分层协作。以x + y为例,从Python前端到算子分发、CUDA运行时,最终在GPU硬件上执行。关键认知包括:GPU并非万能加速器,小任务因开销大反而更慢;.to('cuda')仅搬运数据,不改变代码逻辑;算子性能受算术强度与内存带宽制约。理解此链路是优化深度学习性能的前提。 阅读详情

相关推荐

Windows 游戏 EXCEPTION_ACCESS_VIOLATION 修复:3类硬件问题与5步软件排查法

本文提供Windows游戏EXCEPTION_ACCESS_VIOLATION错误的终极修复指南,涵盖3类硬件问题(内存故障、显卡问题、超频不稳定)和5步软件排查法(文件验证、驱动更新、DEP调整等),帮助玩家彻底解决0xFFFFFFFFFFFFFFFF内存访问冲突问题。

weixin_31856057的博客 2392

python识别数字程序_详解python实现识别手写MNIST数字集的程序

我们需要做的第⼀件事情是获取 MNIST 数据。如果你是⼀个 git ⽤⼾,那么你能够通过克隆这本书的代码仓库获得数据,实现我们的⽹络来分类数字git clone class Network(object): def __init__(self, sizes): self.num_layers = len(sizes) self.sizes = sizes self.biases = [np.ra...

weixin_39836943的博客 260

运维面试常见问题

对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。优缺点:优点:利用索引可以加速对数据的检索,索引是可以唯一的,创建索引允许指定单个列或者多个列缺点:减慢了数据录入速度,同时也增加了数据库的尺寸大小。

asdmjy123的博客 1365

python3编程100例-Python3经典100例(④)

实例16题目:输出指定格式的日期;代码:#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2019/3/5 22:47# @Author : cunyu# @Site : cunyu1943.github.io# @File : sixteen.py# @Software: PyCharmimport datetimei...

weixin_37988176的博客 2812

Altium Designer20-柔性PCB绘制技巧

Altium Designer2020-柔性PCB绘制技巧 注:教程所用PCB随意找的,并没有完全绘制完,大家学习PCB折弯方法即可。 1.打开PCB,点击视图->板子规划模式1,如下图所示 2.点击设计->定义分割线,用两条分割线绘出要折弯的区域 3.点击设计->定义弯曲线(弯曲线呈现黄色) 4.用快捷键d,k进入layer manage stack(层叠管理器),在f...

weixin_44450279的博客 1万+

27、自闭症儿童治疗与玩具设计研究

本研究探讨了自闭症儿童的治疗方法与玩具设计之间的关联,分析了游戏疗法、音乐疗法和职业疗法等在治疗中的应用,并介绍了多种针对自闭症儿童的治疗玩具案例。通过用户研究和多学科合作,提出了以Pro-Ability为核心的设计理念,开发了结合音乐疗法和精细运动训练的智能玩具套件。研究总结了当前成果与局限性,并展望了未来发展方向,旨在为自闭症儿童提供更有效的康复支持。

keras9composer的博客 210

pytorch:pokemon+resnet详细代码+数据集

用resnet实现pokemon的划分。详细代码+解释+完整数据集资源

weixin_41391619的博客 2012

anaconda navigator 卡在loading application界面一直没有反应解决办法

在打开anaconda navigator 程序的时候,遇到了2个问题。第一个问题:打开的时候弹出提示:There is an instance of Anaconda Navigator already running.第二个问题:程序一直卡在loading application界面一直没有反应。以下是我的解决办法,有效果。

猿小白的博客 4383

李宏毅机器学习第三周_神奇宝贝分类、逻辑回归

本文主要介绍了深度学习中分类问题的解决方法,以神奇宝贝分类为例,通过选取适当的函数和损失函数,以及使用算法如朴素贝叶斯、逻辑回归和多分类算法进行分类预测。对于逻辑回归,其基本原理是将输入特征通过线性加权求和,并经过sigmoid函数转化为0-1之间的值,从而得到样本为正的概率,最后通过交叉熵损失函数优化模型预测结果。需要注意的是,在分类分界线不为直线的情况下,需要进行特征转换或使用多个模型的方法进行解决。

weixin_48772700的博客 964

多模态大模型在AI人工智能领域的创新实践探索

随着人工智能技术的飞速发展,单一模态的数据处理已经难以满足复杂现实场景的需求。多模态大模型通过融合多种模态的数据,如文本、图像、音频等,能够更全面、深入地理解和处理信息,为人工智能的发展带来了新的机遇和挑战。本文的目的在于深入探讨多模态大模型在AI人工智能领域的创新实践,包括其核心概念、算法原理、实际应用等方面,旨在为相关领域的研究人员和从业者提供全面的技术参考和实践指导。本文的范围涵盖了多模态大模型的基本原理、算法实现、数学模型、项目实战以及实际应用场景等多个方面。

大模型应用工坊 1316

Trae 在代码审查场景的 3 大差异化能力:对比 Claude Code、Cursor 与 Codex 实测

揭示代码审查的核心矛盾是上下文断层而非找 Bug,介绍 Trae 通过跨文件符号追踪、意图-实现对齐校验、增量变更影响图谱生成三件事实现上下文校准,并对比其与 Claude Code、Cursor、Codex 在多模块 Java 项目中的实际审查差异

weixin_42525482的博客 151

Neural Networks and Deep Learning读书笔记--神经网络改进原理代码(network2)

和 network.py 一样,主要部分就是 Network 类了,用这个来表示神经网络。使用一个 sizes 的列表来对每个对应层进行初始化,默认使用交叉熵作为代价 cost 参数: class Network(object): def __init__(self, sizes, cost=CrossEntropyCost): self.num_layers = len(sizes) self.sizes = sizes self.default_

qq_43131605的博客 523

AS7341可见光谱传感器原理图设计,已量产(光线传感器)

最近在做便携式环境光光谱检测项目时,我们基于 ams 的 AS7341 搭了一套硬件电路 —— 这颗芯片算是业内新一代的光谱传感 IC,8 个可见光通道 + NIR + 闪烁检测的配置,加上 6 路并行 16 位 ADC,数据吞吐能力确实够顶。今天就拆解下这个模块的硬件设计细节,聊聊实际做板时的那些考量点。

不脱发的程序猿 639

简单神经网络实现

import numpy as np # 定义神经网络结构 class Network(object): def __init__(self, sizes): # [3,2,1] 输入层3个神经元,隐藏层2个,输出层1个 定义总共有多少层,每一层有多少个神经元 # 网络层数: 一共有多少层 self.num_layers = len(siz...

m0_37598149的博客 356

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

基于Pytorch的卷积神经网络AlexNet网络的代码编写

AlexNet网络结构基于Pytorch编写 一、AlexNet模型 -网络总体结构 -各模块之间的联系 从上面两图中我们可以将AlexNet模型分为 1. Features 2. Classifier 二、Features -图解模型 从图中我们可以看出AlexNet对图像的处理顺序为: 卷积->relu激活->最大池化-> 卷积->relu激活->最大池化-> 卷积->relu激活->卷积->relu激活->卷积->relu激

Larryzx的博客 543

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【从零开始学习深度学习】50.Pytorch_NLP项目实战:卷积神经网络textCNN在文本情感分类的运用

【从零开始学习深度学习】50.Pytorch_NLP项目实战:卷积神经网络textCNN在文本情感分类的运用

阿旭的博客 1204

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

python神经网络模型_python实现BP神经网络回归预测模型

神经网络模型一般用来做分类,回归预测模型不常见,本文基于一个用来分类的BP神经网络,对它进行修改,实现了一个回归模型,用来做室内定位。模型主要变化是去掉了第三层的非线性转换,或者说把非线性激活函数Sigmoid换成f(x)=x函数。这样做的主要原因是Sigmoid函数的输出范围太小,在0-1之间,而回归模型的输出范围较大。模型修改如下:代码如下:#coding: utf8''''author: H...

weixin_39631899的博客 1994

帮我解释一下下面的代码:class NeuralNetwork(nn.Module): def __init__(self): super(NeuralNetwork, sel...

这段代码定义了一个名为NeuralNetwork的类,它继承自PyTorch中nn.Module类。在这个类的初始化函数中,使用了super()函数来调用nn.Module的初始化函数。然后定义了两个nn.Module子类,一个是nn.Flatten类,另一个是nn.Sequential类。nn.Flatten类可以将输入的多维张量展平成一维张量,nn.Sequential类则可以将多个nn.Mo...

weixin_35753431的博客 434

神经网络 python实现

本文是将mnist的分类测试,神经网络的python实现 文章的加载路径也是电脑本地的路径,所以应用时注意路径和读取数据的名称的关系 读取mnist数据集,输出结果是一矩阵,每一列为一张图片拉成的向量 import struct import os import numpy as np from matplotlib import pyplot as plt class MNIST(object): ''' MNIST数据集类 ''' def __init__(self,ro

weixin_40253737的博客 308

自定义数据集(Pokemon)实战

Load data inherit from torch.utils.data.Dataset __len__返回一个样本数量 __getitem__去读取一个具体的样本 大致的逻辑为:完成初始化工作,把所有图片信息加载进来,图片的路径和label根据mode模式是train还是valid做各种裁剪得到样本数量和具体样本,返回的img和label就是对应idx的自定义数据tensor类型 class NumberDataset(Dataset): def __init__(self, training=T

weixin_43955293的博客 3439

深度学习笔记(四)利用神经网络分类数字 含python代码

利用神经网络分类数字利用我们的神经网络来分类数字前言代码正式部分 利用我们的神经网络来分类数字 前言 Tips: 你可以在终端git编者的代码 git clone https://github.com/mnielsen/neural-networks-and-deep-learning.git 对MINIST的使用,我们将用50000张图片进行训练我们的神经网络,用10000张图片来作为我们的va...

等待戈多的博客 1311

python手写识别mnist_详解python实现识别手写MNIST数字集的程序

我们需要做的第⼀件事情是获取 MNIST 数据。如果你是⼀个 git ⽤⼾,那么你能够通过克隆这本书的代码仓库获得数据,实现我们的⽹络来分类数字git clone https://github.com/mnielsen/neural-networks-and-deep-learning.gitclass Network(object):def __init__(self, sizes):self....

weixin_29527111的博客 425

Pytorch Dataset与DataLoader数据集加载

上一节我们学会了损失函数、优化器和基础训练循环。但是之前示例是手写少量tensor数据,真实项目图片成千上万,需要一套规范的数据加载方案。数据集抽象类,定义怎么拿单条样本(索引取数据)加载器,对Dataset包装,实现batch、shuffle、多进程读取数据流水线:原始数据 → Dataset读取单样本 → Transform预处理 → DataLoader打包成batch送入网络__len__:返回数据集总样本数量,调用:按下标取一个样本,调用。

Beforthing的博客 221

【从零手写GPT(一)】:RTX 5080 环境踩坑,我装错了两次 PyTorch

C++老兵从零手写GPT系列首篇,记录在RTX 5080环境下配置PyTorch的踩坑历程。因误装CPU版导致CUDA不可用,后通过南京大学镜像正确安装torch-2.11.0+cu128,验证成功识别sm_120架构并完成GPU矩阵乘法。进一步跑通线性回归训练循环,参数收敛至理论值,确认环境可用。以C++视角理解Tensor、autograd与nn.Module,为后续GPT实现奠基。

weixin_51122602的博客 227

机器学习教程,从入门到精通,深度学习入门语法知识点完全指南(PyTorch 版)(12)

本文为零基础读者量身定制的PyTorch深度学习入门指南,系统讲解深度学习核心原理与实战语法。从神经元、激活函数、损失函数等基础概念入手,结合Sigmoid、ReLU、MSE、CrossEntropy等关键知识点,辅以可运行的PyTorch代码示例,逐行注释详解。涵盖线性回归、CNN、GAN、ResNet等八大典型应用,揭示其在推荐系统、自动驾驶、医疗影像等企业场景中的实际价值,帮助读者快速掌握“原理—框架—应用”全链路技能。

qq_45746668的博客 330

Pytorch 神经网络基础(nn.Module、卷积层、池化层、线性层)

前面我们学习了张量Tensor、自动求导Autograd,这两个是Pytorch最底层的基石。在真实项目中,我们不会手动去写大量求导逻辑,torch.nn模块封装好了神经网络各类层、损失函数,让我们快速搭建网络。本篇重点讲解nn.Module以及常用网络层:卷积Conv、池化Pool、全连接Linear。,和opencv、PIL的HWC相反!卷积之后进全连接,一定要flatten展平,否则维度对不上padding的作用:控制特征图尺寸不变,same padding池化层不改变通道数,只缩小高宽。

Beforthing的博客 148
上一篇: 1.3个维度的矩阵投影,2.不用遍历而改变满足条件的矩阵元素
下一篇: 【解决】can‘t convert CUDA tensor to numpy. Use Tensor.cpu to copy the tensor to host memory first
WinrenJoe
博客等级 码龄8年 67粉丝 14原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值