惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

HANG ♥ WRITING

Agents 当道,我们都可以被蒸馏成 Skills ChatGPT 问世两年,我在 AI 的辅助下成为了一名 iOS 业余开发者 如何使用 Netcat 构建简单的安全聊天系统 QuakeSense 震感,一款简洁原生的 iOS 地震通知 App App Store 中国大陆 ICP 备案最佳实践 几款有意思的 Google Chrome 侧边栏扩展应用 GetVM 让编程学习更快一步 WildCard (野卡) - 国内用户零门槛订阅 ChatGPT、Claude、App Store 万里汇开发者收款使用全指南 | 注册、开户与账户绑定教程 中国大陆居民开通华侨银行(OCBC)海外账户完全指南 实用的 macOS 内置命令,省下买第三方应用的钱 《认知觉醒》之触动学习法 不是程序员也可以搞开发,一小时入门 Retool 低代码 疫情来袭,手把手教你在家制作美味炒鸡 企业微信机器人 Webhook 推送语雀更新消息 基于 Cloudflare Workers 部署的 JSON Database 数据库 印象时间:印象笔记出品的时间管理应用 Pixelmator Photo 2.0: 桌面级功能并适配 iPhone Shortery:Mac 快捷指令自动化 Pixelmator Pro 2.3:AI 背景去除 Quit All:一键退出应用程序 Raycast:推出官方扩展商店和开发者平台 简悦 API 2.0:收藏助手和快照功能 HomePod mini 使用体验 Prizmo 5.5:扫描效果增强并新增批注功能 Notion:近期值得关注的新特性 Google Analytics 替代品,零成本和零门槛搭建 umami.is Infuse 7:一款近乎完美的视频播放器 Gyroscope 4.14:新的产品名称和多项改进 V day:在手机上创作短视频 Things 3.14:备注支持 Markdown,同步速度加快 MoneyWiz 2021:新的通知选项和视觉改善 Doppler:管理和分享你的本地音乐 CARROT Weather:5.3 带了多项新特性 Obsidian:知名知识管理工具推出移动应用 NOMO RAW:专业 ProRAW 相机 Tape:全能且好用的录屏软件 Apple Design Award 2021 Craft 1.6:每日笔记重磅更新 Trakt:官方 iOS 应用全新上线 Notion:支持 API 和自动化集成 Varlens:iOS 专业相机应用 Infuse 7:不只是 M1,支持所有 Mac 简悦:支持 API 和自动化流程 奇妙组件:小而美的自定义 iOS 小组件 Farbox 2:支持自部署和多站点的开源博客系统 图图记账:高颜值记账应用 Coppice:帮助整理你的想法 DarkModeBuddy:基于光线切换深色模式 走进微软成都 Office,聊一聊 Microsoft 365 HapiGo:符合国情的效率启动器 Eagle 2.0:数十项功能更新 + 数倍的性能提升 无需记账,通过更新余额了解自己有「多少资产」 Dato:支持日历和时区的菜单栏时钟 极具潜力的效率启动器 App,Raycast 脚本功能详解 Pixelmator Pro 2.0.2:增加新效果,支持 ProRAW Raycast:面向开发人员的效率启动器 Sorted:全新的 Mac 版本,原生支持 Apple Silicon App Store 和 Google Play 的 2020 年度 App 榜单 VSCO:全新的视频效果和拍摄模式 Pixelmator Pro 2.0:全新设计并支持 M1 芯片 Maipo 4:全功能新浪微博 macOS 客户端 Bartender 4:Mac 菜单栏定制工具 JSBox:适配并支持 iOS 14 小组件 Little Snitch 5:macOS 上出色的流量监控与防火墙应用 Photoshop:更多的 AI 创意工具 Capslox:文本操作快捷键增强效率工具 Airport:TestFlight 测试应用商店 Disk Drill 4:全新设计,支持 macOS 11 Big Sur OneWidget:小组件中的瑞士军刀 Todoist:新增看板视图 IFTTT Pro:合理的定价、全新的特性 PooPoo Privacy Policy QuakeSense Privacy Policy | 震感 App 隐私政策 ThenNow Privacy Policy | 今昔 App 隐私政策 LaunchBar 6.13:支持 macOS Big Sur 24 Hour Wallpaper:近百张 Mac 动态壁纸 简悦 2.0 阅读模式 + 标注系统 + 稍后读 绕过 App Store 付费,Setapp 采用新的 iOS 付费应用解锁策略 Noto 笔记:2.3 版本带来 10 余项功能更新 PliimPRO:让 Mac 一键进入演示模式 Pixelmator Pro 1.7:文字输入、画布旋转和 ML 超分辨率更新 Ulysses 20:新增导航面板和中文拼写检查 Mailbrew:新增 Inbox 集中订阅 Newletter Fluent Reader:免费跨平台 RSS 阅读器 Moment:高颜值 Mac 状态栏倒数日应用 Meeter:集中管理你的远程会议 Adobe Lightroom:新版带来了众多实用特性 WWDC:在 Mac 上观看 WWDC 直播和视频 LongWe:Mac 上的文本长图生成工具 Photoshop Camera:风格独特的艺术效果 Empoche:任务管理和时间追踪二合一 Camera+ 2:Magic ML 带来照片处理新魔法 Tuck:将窗口停靠在屏幕边缘 Wormhole:在电脑上操作 iOS 和 Android 设备 Coherence X:一键将网页转换为桌面应用 Charty:让快捷指令支持图表可视化 Edison Mail:又一款免费邮件客户端 Service Station:定制 Mac 右键菜单 WatchSmith:前所未有地个性化 Apple Watch
LeNet-5 卷积神经网络的 4 种实现方法
huhuhang@gmail.com (huhuhang) · 2019-02-19 · via HANG ♥ WRITING

LeNet-5 是 LeCun 在 1998 年发明的卷积神经网络 ,其结构简单,很适合初学者用来学习卷积神经网络的构建方法。

下面,我们将使用 TensorFlow 和 PyTorch 提供的低阶和高阶 API 来构建 LeNet-5 网络,总共会用到 4 种不同的方法。

TensorFlow 低阶 API 构建

TensorFlow 低阶 API 主要是利用 tf.nn 模块提供的相关函数或类方法。特别注意的是,你需要自行初始化卷积核权重和全连接层的截距项。


import tensorflow as tf

def LeNet(x):

    # 卷积核权重
    weights = {
        'conv1': tf.Variable(tf.random_normal(shape=(5, 5, 1, 6))),
        'conv2': tf.Variable(tf.random_normal(shape=(5, 5, 6, 16))),
        'fc1': tf.Variable(tf.random_normal(shape=(5*5*16, 120))),
        'fc2': tf.Variable(tf.random_normal(shape=(120, 84))),
        'out': tf.Variable(tf.random_normal(shape=(84, 10))),
    }

    # 卷积层 1: Input = 32x32x1. Output = 28x28x6.
    conv1 = tf.nn.conv2d(x, weights['conv1'], strides=[1, 1, 1, 1], padding='VALID')
    # RELU 激活
    conv1 = tf.nn.relu(conv1)
    # 池化层 1: Input = 28x28x6. Output = 14x14x6.
    pool1 = tf.nn.avg_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
    # 卷积层 2: Input = 14x14x6. Output = 10x10x16.
    conv2 = tf.nn.conv2d(pool1, weights['conv2'], strides=[1, 1, 1, 1], padding='VALID')
    # RELU 激活
    conv2 = tf.nn.relu(conv2)
    # 池化层 2: Input = 10x10x16. Output = 5x5x16.
    pool2 = tf.nn.avg_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
    # 展平。Input = 5x5x16. Output = 400.
    flatten = tf.reshape(pool2, [-1, 5*5*16])

    # 截距项
    biases = {
        'fc1': tf.Variable(tf.zeros(120)),
        'fc2': tf.Variable(tf.zeros(84)),
        'out': tf.Variable(tf.zeros(10))
    }

    # 全连接层
    fc1 = tf.nn.relu(tf.add(tf.matmul(flatten, weights['fc1']), biases['fc1']))
    fc2 = tf.nn.relu(tf.add(tf.matmul(fc1, weights['fc2']), biases['fc2']))
    outs = tf.add(tf.matmul(fc2, weights['out']), biases['out'])

    return outs

LeNet-5 要求的传入数据尺寸是 [32, 32, 1],所以像常用的 MNIST 等数据集都需要预先处理成规定的形状才能使用该网络函数。

TensorFlow 高阶 API 构建

目前,Keras 已正式合并入 TensorFlow。所以 TensorFlow 的高阶 API 及可以通过 tf.keras 来构建。我们这里使用序贯模型结构,很方便地搭建出 LeNet-5 网络。这也是最简单的方法之一。

import tensorflow as tf

model = tf.keras.Sequential()  # 构建序贯模型

# 卷积层,6 个 5x5 卷积核,步长为 1,relu 激活,第一层需指定 input_shape
model.add(tf.keras.layers.Conv2D(filters=6, kernel_size=(5, 5), strides=(1, 1),
                                 activation='relu', input_shape=(32, 32, 1)))
# 平均池化,池化窗口默认为 2
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
# 卷积层,16 个 5x5 卷积核,步为 1,relu 激活
model.add(tf.keras.layers.Conv2D(filters=16, kernel_size=(
    5, 5), strides=(1, 1), activation='relu'))
# 平均池化,池化窗口默认为 2
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
# 需展平后才能与全连接层相连
model.add(tf.keras.layers.Flatten())
# 全连接层,输出为 120,relu 激活
model.add(tf.keras.layers.Dense(units=120, activation='relu'))
# 全连接层,输出为 84,relu 激活
model.add(tf.keras.layers.Dense(units=84, activation='relu'))
# 全连接层,输出为 10,Softmax 激活
model.add(tf.keras.layers.Dense(units=10, activation='softmax'))
# 查看网络结构
model.summary()

除此之外,你还可以使用 TensorFlow 提供的 Estimator 高阶 API 来构建,这里不再赘述。详细可参阅 官方文档

PyTorch 低阶 API 构建

相比于 TensorFlow,PyTorch 拥有无需管理会话,自动求导等机制,越来越多的研究人员偏好使用。使用 PyTorch 实现 LeNet-5 时,需要继承 nn.Module 基类,然后使用 torch.nn 提供的类或 torch.nn.functional 提供的函数来组合模型结构。

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

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        # 卷积层 1
        self.conv1 = nn.Conv2d(
            in_channels=1, out_channels=6, kernel_size=(5, 5), stride=1)
        # 池化层 1
        self.pool1 = nn.AvgPool2d(kernel_size=(2, 2))
        # 卷积层 2
        self.conv2 = nn.Conv2d(
            in_channels=6, out_channels=16, kernel_size=(5, 5), stride=1)
        # 池化层 2
        self.pool2 = nn.AvgPool2d(kernel_size=(2, 2))
        # 全连接层
        self.fc1 = nn.Linear(in_features=5*5*16, out_features=120)
        self.fc2 = nn.Linear(in_features=120, out_features=84)
        self.fc3 = nn.Linear(in_features=84, out_features=10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.pool1(x)
        x = F.relu(self.conv2(x))
        x = self.pool2(x)
        x = x.reshape(-1, 5*5*16)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.softmax(self.fc3(x), dim=1)
        return x

PyTorch 高阶 API 构建

实际上,PyTorch 也提供了 nn.Sequential 容器结构,类似于 Keras 的使用过程。nn.Sequential 可以简化模型的构建过程,直接使用 torch.nn 提供的类来组合即可。注意,PyTorch 中未提供 Flatten 类,所以需要使用 reshape 操作预先定义一个。

import torch.nn as nn

class Flatten(nn.Module):
    def forward(self, input):
        return input.reshape(input.size(0), -1)

# 构建 Sequential 容器结构
model = nn.Sequential(
    nn.Conv2d(1, 6, (5, 5), 1),
    nn.ReLU(),
    nn.AvgPool2d((2, 2)),
    nn.Conv2d(6, 16, (5, 5), 1),
    nn.ReLU(),
    nn.AvgPool2d((2, 2)),
    Flatten(),
    nn.Linear(5*5*16, 120),
    nn.ReLU(),
    nn.Linear(120, 84),
    nn.ReLU(),
    nn.Linear(84, 10),
    nn.Softmax(dim=1)
)

上面即是如何使用 TensorFlow 和 PyTorch 实现经典卷积神经网络 LeNet-5 的 4 种方法。当然,这里只搭建了模型的主体结构,如果要正常开始训练,还需要对数据预处理或补充模型训练和测试代码。更多的细节内容,可以结合框架的官方文档来实现。