第20周:Pytorch文本分类入门
目录
前言
一、前期准备
1.1 环境安装导入包
1.2 加载数据
1.3 构建词典
1.4 生成数据批次和迭代器
二、准备模型
2.1 定义模型
2.2 定义示例
2.3 定义训练函数与评估函数
三、训练模型
3.1 拆分数据集并运行模型
3.2 使用测试数据集评估模型
总结
前言
🍨 本文为[🔗365天深度学习训练营]中的学习记录博客
🍖 原作者:[K同学啊]
说在前面
本周任务:了解文本分类的基本流程、学习常用数据清洗方法、学习如何使用jieba实现英文分词、学习如何构建文本向量
我的环境:Python3.8、Pycharm2020、torch1.12.1+cu113
数据来源:[K同学啊]
一、前期准备
1.1 环境安装导入包
本文是一个使用Pytorch实现的简单文本分类实战案例,在本案例中,我们将使用AG News数据集进行文本分类
需要确保已经安装了torchtext与poralocker库
PS:torchtext库的安装需要与Pytorch、python的版本进行匹配,具体可参考torchtext版本对应
import torch
import torch.nn as nn
import torchvision
from torchvision import transforms, datasets
import os,PIL,pathlib,warnings
from torchtext.datasets import AG_NEWS
from torchtext.vocab import build_vocab_from_iterator
import torchtext.data.utils as utils
from torch.utils.data import DataLoader
from torch import nn
import timewarnings.filterwarnings("ignore")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)
1.2 加载数据
本文使用的数据集是AG News(AG's News Topic Classification Dataset)是一个广泛用于文本分;分类任务的数据集,尤其是在新闻领域,该数据集是由AG’s Corpus of News Ariticles收集整理而来,包含了四个主要的类别:世界、体育、商业和科技
torchtext.datasets.AG_NEWS是一个用于加载AG News数据集的torchtext数据集类,具体的参数如下:
- root:数据集的根目录,默认值是'.data'
- split:数据集的拆分train、test
- **kwargs:可选的关键字参数,可传递给torchtext.datasets.TextClassificationDataset类构造的函数
该类加载的数据集是一个列表,其中每个条目都是一个元祖,包含以下两个元素
- 一条新闻文章的文本内容
- 新闻文章所属的类别(一个整数,从1到4,分别对应世界、科技、体育和商业)
代码如下:
train_iter = AG_NEWS(split='train')
1.3 构建词典
torchtext.data.ttils.get_tokenizer()是一个用于将文本数据分词的函数,它返回一个分词器(tokenizer)函数,可以将一个字符串转换成一个单词的列表
函数原型:torchtext.data.ttils.get_tokenizer(tokenizer, language = 'en')
tokenizer参数是用于指定使用的分词器名称,可以是一下之一
- basic_english:用于基本英文文本的分词器
- moses:用于处理各种语言的分词器,支持多种选项
- spacy:使用spaCy分词器,需要安装spaCy库
- toktok:用于各种语言的分词器,速度较快
PS:分词器函数返回的单词列表中不包含任何标点符号或空格
代码如下:
tokenizer = utils.get_tokenizer('basic_english')def yield_tokens(data_iter):for _, text in data_iter:yield tokenizer(text)vocab = build_vocab_from_iterator(yield_tokens(train_iter),specials=["<unk>"])
vocab.set_default_index(vocab["<unk>"]) #设置默认索引,如果找不到单词,则会选择默认索引print(vocab(['here', 'is', 'an', 'example']))text_pipeline = lambda x: vocab(tokenizer(x))
label_pipeline = lambda x: int(x) - 1print(text_pipeline('here is an example'))
print(label_pipeline('10'))
输出结果:
[475, 21, 30, 5297]
[475, 21, 30, 5297]
9
1.4 生成数据批次和迭代器
代码如下:
def collate_batch(batch):label_list, text_list, offsets = [],[],[0]for (_label, _text) in batch:# 标签列表label_list.append(label_pipeline(_label))# 文本列表processed_text = torch.tensor(text_pipeline(_text),dtype=torch.int64)text_list.append(processed_text)#偏移量,即语句的总词汇量offsets.append(processed_text.size(0))label_list = torch.tensor(label_list, dtype=torch.int64)text_list = torch.cat(text_list)offsets = torch.tensor(offsets[:-1]).cumsum(dim=0)return label_list.to(device),text_list.to(device), offsets.to(device)#数据集加载器
dataloader = DataLoader(train_iter, batch_size=8, shuffle=False, collate_fn=collate_batch)
二、准备模型
2.1 定义模型
首先对文本进行嵌入,然后对句子嵌入之后的结果进行均值聚合
代码如下:
#2.1 准备模型
class TextClassificationModel(nn.Module):def __init__(self,vocab_size,embed_dim,num_calss):super(TextClassificationModel, self).__init__()self.embedding = nn.EmbeddingBag(vocab_size, embed_dim, sparse=False)self.fc = nn.Linear(embed_dim, num_calss)self.init_weights()def init_weights(self):initrange = 0.5self.embedding.weight.data.uniform_(-initrange, initrange)self.fc.weight.data.uniform_(-initrange, initrange)self.fc.bias.data.zero_()def forward(self, text, offsets):embedded = self.embedding(text, offsets)return self.fc(embedded)
self.embedding.weight.data.uniform_(-initrange, initrange)是在PyTorch框架下用于初始化神经网络的词嵌入层(embedding layer)权重的一种方法,这里使用了均匀分布的随机值来初始化权重,具体来说,其作用如下:
- self.embedding:这是神经网络的词嵌入层(embedding layer),其嵌入层的作用是将离散的单词表示(通常为整数索引)映射为固定大小的连续向量,这些向量捕捉了单词之间的语义关系,并作为网络的输入
- self.embedding.weight:这是词嵌入层的权重矩阵,它的形状为(vocab_size,embedding_dim),其中vocab_size是词汇表的大小,embedding_dim是嵌入向量的维度
- self.embedding.weight.data:这是权重矩阵的数据部分,可以直接操作其底层的张量
- .uniform_(-initrange, initrange):这是一个原地操作,用于将权重矩阵的值用一个均匀分布进行初始化,均匀分布的范围为[-initrange,initrange],其中initrange是一个正数
这种方式初始化词嵌入层的权重,可以使得模型在训练开始时具有一定的随机性,有助于避免梯度消失或梯度爆炸等问题,在训练过程中,这些权重将通过优化算法不断更新,以捕捉到更好的单词表示
2.2 定义示例
代码如下:
#2.2定义实例
num_class = len(set([label for (label,text) in train_iter]))
vocab_size = len(vocab)
em_size = 64
model = TextClassificationModel(vocab_size, em_size, num_class).to(device)epochs = 10
lr = 5
batch_szie =64critertion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=lr)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer,1.0,gamma=0.1)
2.3 定义训练函数与评估函数
#2.3 定义训练函数与评估函数
def train(dataloader):model.train()total_acc, train_loss, total_count = 0,0,0log_interval = 500start_time = time.time()for idx, (label, text, offsets) in enumerate(dataloader):predicted_label = model(text, offsets)optimizer.zero_grad()loss = critertion(predicted_label, label)loss.backward()optimizer.step()#记录acc和losstotal_acc += (predicted_label.argmax(1) == label).sum().item()train_loss += loss.item()total_count += label.size(0)if idx % log_interval == 0 and idx>0:elapsed = time.time() - start_timeprint('| epoch{:1d} | {:4d}/{:4d} batches''train_acc {:4.3f} train_loss {:4.5f}'.format(epoch, idx, len(dataloader),total_acc/total_count, train_loss/total_count))total_acc, train_loss, total_count = 0, 0, 0start_time = time.time()def evaluate(dataloader):model.eval()total_acc, train_loss, total_count = 0, 0 ,0with torch.no_grad():for idx, (label, text, offsets) in enumerate(dataloader):predicted_label = model(text, offsets)loss = critertion(predicted_label, label)# 记录acc和losstotal_acc += (predicted_label.argmax(1) == label).sum().item()train_loss += loss.item()total_count += label.size(0)return total_acc/total_count, train_loss/total_count
三、训练模型
3.1 拆分数据集并运行模型
torchtext.data.functional.to_map_style_dataset函数的作用是将一个迭代式的数据集(Iterable-style dataset)转换为映射式的数据集(Map-style dataset)。这个转换使得我们可以通过索引更方便访问数据集中的元素
在PyTorch中,数据集可以分为两种类型:Iterable-style和Map-style,Iterable-style数据集实现了__iter__()方法,可以迭代访问数据集中的元素,但不支持通过索引访问,而Map-style数据集实现了__getitem__()和__len__()方法,可以直接通过索引访问特定元素,并能获取数据集的大小、
TorchText是Pytorch的一个扩展库,专注于处理文本数据,torchtext.data.functional中的to_map_style_dataset函数可以帮助我们将一个Iterable-style数据集转换为一个易于操作的Map-style数据集,这样就可以通过索引直接访问数据集中的特定样本,从而简化了训练、验证和测试过程中的数据处理。
代码如下:
#3.1 拆分数据集并运行模型
from torch.utils.data.dataset import random_split
from torchtext.data.functional import to_map_style_datasettotal_accu = Nonetrain_iter, test_iter = AG_NEWS()
train_dataset = to_map_style_dataset(train_iter)
test_dataset = to_map_style_dataset(test_iter)
num_train = int(len(train_dataset) * 0.95)
split_train_, split_valid_ = random_split(train_dataset, [num_train, len(train_dataset)-num_train])train_dataloader = DataLoader(split_train_, batch_size=batch_szie, shuffle=True, collate_fn=collate_batch)
vaild_dataloader = DataLoader(split_valid_, batch_size=batch_szie, shuffle=True, collate_fn=collate_batch)
test_dataloader = DataLoader(test_dataset, batch_size=batch_szie, shuffle=True, collate_fn=collate_batch)for epoch in range(1, epochs+1):epoch_start_time = time.time()train(train_dataloader)val_acc, val_loss = evaluate(vaild_dataloader)if total_accu is not None and total_accu > val_acc:scheduler.step()else:total_accu = val_accprint('-' * 69)print('| epoch{:1d} | time: {:4.2f}s |''vaild_acc {:4.3f} vaild_loss {:4.3f}'.format(epoch,time.time()-epoch_start_time,val_acc, val_loss))print('-' * 69)
输出结果:
| epoch1 | 500/1782 batchestrain_acc 0.714 train_loss 0.01141
| epoch1 | 1000/1782 batchestrain_acc 0.864 train_loss 0.00623
| epoch1 | 1500/1782 batchestrain_acc 0.879 train_loss 0.00551
---------------------------------------------------------------------
| epoch1 | time: 7.21s |vaild_acc 0.810 vaild_loss 0.008
---------------------------------------------------------------------
| epoch2 | 500/1782 batchestrain_acc 0.905 train_loss 0.00445
| epoch2 | 1000/1782 batchestrain_acc 0.905 train_loss 0.00440
| epoch2 | 1500/1782 batchestrain_acc 0.906 train_loss 0.00442
---------------------------------------------------------------------
| epoch2 | time: 5.68s |vaild_acc 0.910 vaild_loss 0.004
---------------------------------------------------------------------
| epoch3 | 500/1782 batchestrain_acc 0.915 train_loss 0.00389
| epoch3 | 1000/1782 batchestrain_acc 0.918 train_loss 0.00381
| epoch3 | 1500/1782 batchestrain_acc 0.918 train_loss 0.00377
---------------------------------------------------------------------
| epoch3 | time: 6.04s |vaild_acc 0.910 vaild_loss 0.004
---------------------------------------------------------------------
| epoch4 | 500/1782 batchestrain_acc 0.929 train_loss 0.00331
| epoch4 | 1000/1782 batchestrain_acc 0.921 train_loss 0.00357
| epoch4 | 1500/1782 batchestrain_acc 0.926 train_loss 0.00341
---------------------------------------------------------------------
| epoch4 | time: 6.54s |vaild_acc 0.890 vaild_loss 0.005
---------------------------------------------------------------------
| epoch5 | 500/1782 batchestrain_acc 0.941 train_loss 0.00280
| epoch5 | 1000/1782 batchestrain_acc 0.945 train_loss 0.00266
| epoch5 | 1500/1782 batchestrain_acc 0.944 train_loss 0.00265
---------------------------------------------------------------------
| epoch5 | time: 6.76s |vaild_acc 0.917 vaild_loss 0.004
---------------------------------------------------------------------
| epoch6 | 500/1782 batchestrain_acc 0.948 train_loss 0.00255
| epoch6 | 1000/1782 batchestrain_acc 0.946 train_loss 0.00265
| epoch6 | 1500/1782 batchestrain_acc 0.946 train_loss 0.00260
---------------------------------------------------------------------
| epoch6 | time: 6.80s |vaild_acc 0.920 vaild_loss 0.004
---------------------------------------------------------------------
| epoch7 | 500/1782 batchestrain_acc 0.948 train_loss 0.00254
| epoch7 | 1000/1782 batchestrain_acc 0.945 train_loss 0.00266
| epoch7 | 1500/1782 batchestrain_acc 0.949 train_loss 0.00248
---------------------------------------------------------------------
| epoch7 | time: 6.52s |vaild_acc 0.915 vaild_loss 0.004
---------------------------------------------------------------------
| epoch8 | 500/1782 batchestrain_acc 0.949 train_loss 0.00246
| epoch8 | 1000/1782 batchestrain_acc 0.949 train_loss 0.00246
| epoch8 | 1500/1782 batchestrain_acc 0.949 train_loss 0.00252
---------------------------------------------------------------------
| epoch8 | time: 6.75s |vaild_acc 0.919 vaild_loss 0.004
---------------------------------------------------------------------
| epoch9 | 500/1782 batchestrain_acc 0.948 train_loss 0.00251
| epoch9 | 1000/1782 batchestrain_acc 0.949 train_loss 0.00247
| epoch9 | 1500/1782 batchestrain_acc 0.950 train_loss 0.00245
---------------------------------------------------------------------
| epoch9 | time: 6.87s |vaild_acc 0.919 vaild_loss 0.004
---------------------------------------------------------------------
| epoch10 | 500/1782 batchestrain_acc 0.951 train_loss 0.00244
| epoch10 | 1000/1782 batchestrain_acc 0.947 train_loss 0.00255
| epoch10 | 1500/1782 batchestrain_acc 0.949 train_loss 0.00244
---------------------------------------------------------------------
| epoch10 | time: 6.64s |vaild_acc 0.919 vaild_loss 0.004
---------------------------------------------------------------------
3.2 使用测试数据集评估模型
代码如下:
print('Checking the results of test dataset.')
test_acc, test_loss = evaluate(test_dataloader)
print('test accuracy {:8.3f}'.format(test_acc))
输出结果:
总结
了解文本分类的基本流程、学习常用数据清洗方法、学习如何使用jieba实现英文分词、学习如何构建文本向量
相关文章:

第20周:Pytorch文本分类入门
目录 前言 一、前期准备 1.1 环境安装导入包 1.2 加载数据 1.3 构建词典 1.4 生成数据批次和迭代器 二、准备模型 2.1 定义模型 2.2 定义示例 2.3 定义训练函数与评估函数 三、训练模型 3.1 拆分数据集并运行模型 3.2 使用测试数据集评估模型 总结 前言 …...

记一次 SpringBoot2.x 配置 Fastjson请求报 internal server 500
1.遇到的问题 报错springboot从2.1.16升级到2.5.15,之后就报500内部错误,后面调用都是正常的,就考虑转换有错。 接口返回错误: 2.解决办法 因为我用了fastjson,需要转换下,目前可能理解就是springboot-we…...

OSPF笔记
OSPF:开放式最短路径优先协议 使用范围:IGP 协议算法特点:链路状态型路由协议,SPF算法 协议是否传递网络掩码:传递网络掩码 协议封装:基于ip协议封装,协议号为89 一,ospf特点 1…...

IOC容器初始化流程
IOC容器初始化流程 一、概要1.准备上下文prepareRefresh()2. 获取beanFactory:obtainFreshBeanFactory()3. 准备beanFactory:prepareBeanFactory(beanFactory)4. 后置处理:postProcessBeanFactory()5. 调用bean工厂后置处理器:invokeBeanFactoryPostProcessors()6. 注册bea…...

第二季度云计算市场份额榜单:微软下滑,谷歌上升,AWS仍保持领先
2024 年第二季度,随着企业云支出达到 790 亿美元的新高,三大云计算巨头微软、谷歌云和 AWS的全球云市场份额发生了变化。 根据新的市场数据,以下是 2024 年第二季度全球云市场份额结果和六大世界领先者,其中包括 AWS、阿里巴巴、…...

三点确定圆心算法推导
已知a,b,c三点求过这三点的圆心坐标 a ( x 1 , y 1 ) a(x_1, y_1) a(x1,y1) 、 b ( x 2 , y 2 ) b(x_2, y_2) b(x2,y2) 、 c ( x 3 , y 3 ) c(x_3, y_3) c(x3,y3) 确认三点是否共线 叉积计算方式 v → ( X 1 , Y 1 ) u → ( X 2 , Y 2 ) X 1 Y 2 − X 2 Y 1 \…...

神经网络 (NN) TensorFlow Playground在线应用程序
神经网络 (NN) 历史上最重要的发现之一是神经网络 (NN) 的强大功能。 在神经网络中,称为神经元的许多数据层被添加在一起或相互堆叠以计算新的数据级别。 常用的简称: DNN 深度神经网络CNN 卷积神经网络RNN 循环神经网络 神经元 科学家一致认为&am…...

腾讯课堂 离线m3u8.sqlite转成视频
为了广大腾讯课堂用户对于购买的课程不能正常离线播放,构成知识付费损失,故出此文档。 重点:完全免费!!!完全免费!!!完全免费!!! 怎么…...

Linux多路转接
文章目录 IO模型多路转接select 和 pollepoll IO模型 在还在学习语言的阶段,C里使用cin,或者是C使用scanf的时候,总是要等着我们输入数据才执行,这种IO是阻塞IO。下面是比较正式的说法。 阻塞IO: 在内核将数据准备好之前…...

IDEA导入Maven项目的流程配置以常见问题解决
1. 前言 本文主要围绕着在IDEA中导入新Maven项目后的配置及常见问题解决来展开说说。相关的部分软件如下: IntelliJ IDEA 2021.1JDK 1.8Window 2. 导入Maven项目及配置 2.1 导入Maven项目 下面介绍了直接打开本地项目和导入git上的项目两种导入Maven方式。 1…...

【数据分析---- Pandas进阶指南:核心计算方法、缺失值处理及数据类型管理】
前言: 💞💞大家好,我是书生♡,本阶段和大家一起分享和探索数据分析,本篇文章主要讲述了:Pandas进阶指南:核心计算方法、缺失值处理及数据类型管理等等。欢迎大家一起探索讨论&#x…...

2024世界机器人大会将于8月21日至25日在京举行
2024年的世界机器人大会预定于8月21日至25日,在北京经济技术开发区的北人亦创国际会展中心隆重举办。 本届大会以“共育新质生产力 共享智能新未来”为核心主题,将汇聚来自全球超过300位的机器人行业专家、国际组织代表、杰出科学家以及企业家࿰…...

【Linux】lvm被删除或者lvm丢失了怎么办
模拟案例 接下来模拟lvm误删除如何恢复的案例: 模拟删除: 查看vg名: vgdisplayvgcfgrestore --list uniontechos #查看之前的操作 例如我删除的,现场没有删除就用最近的操作文件: 还原: vgcfgrestore…...

疫情防控管理系统
摘 要 由于当前疫情防控形势复杂,为做好学校疫情防控管理措施,根据上级防疫部门要求,为了学生的生命安全,要求学校加强疫情防控的管理。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生&#x…...

永久删除的Android 文件去哪了?在Android上恢复误删除的消息和照片方法?
丢失重要消息和照片可能是一种令人沮丧的经历,尤其是在您没有备份的情况下。但别担心,在本教程中,我们将指导您完成在Android设备上恢复已删除消息和照片的步骤。无论您是不小心删除了它们还是由于软件问题而消失了,这些步骤都可以…...

宠物服务小程序多生态转化
宠物服务如美容造型、医疗、看护寄养等有着不少需求,尤其是年轻人从宠物生活到饮食起居等面面俱到,往往不惜金钱给到较好的环境,如定时除虫、优质食物、玩具、检查身体、服饰; 近些年宠物服务店新开数量也较多,同行竞…...

今天细说一下工业制造行业MES系统
文章目录 前言什么是MES? 前言 最近几个月在做制造行业的MES系统开发,这类面向制造业的系统是今年做的第三个系统了,也算是了解较深的了,和一个之前转行做这一块的朋友聊了聊,他们集团要扩大规模,准备招ME…...

C++ 知识点(长期更新)
C++ 知识点 C/C++1. `cin`, `cin.get()`, `getchar()`, `getline()`, 和 `cin.getline()`的区别。2. 有关 cin >>3. 定义和声明的区别4. `union`、`struct`和`class`的区别5. 深拷贝 vs 浅拷贝6. new 和 malloc 的区别7. 被free回收的内存是立即返还给操作系统吗?为什么…...

Spring AI + 通义千问 入门学习
Spring AI 通义千问 入门学习 文章目录 Spring AI 通义千问 入门学习一,开发环境配置二,项目搭建2.1 pom文件2.2 配置文件 三,AI使用3.1 对话问答3.1.1 普通方式3.1.2 流方式 3.2 文字生成图片 最近AI很火,而Spring也出了Spring…...

38.【C语言】指针(重难点)(C)
目录: 8.const 修饰指针 *修饰普通变量 *修饰指针变量 9.指针运算 *指针或-整数 *指针-指针 *指针关系运算 往期推荐 承接上篇37.【C语言】指针(重难点)(B) 8.const 修饰指针 const 全称 constant adj.不变的 *修饰普通变量 #…...

Vue-05.指令-v-for
v-for 列表渲染,遍历容器的元素或者对象的属性 v-for“列表元素名 in 列表名” <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wi…...

自动驾驶的一些大白话讲解
无人驾驶牛逼吗?我来帮你祛魅【原理缺陷解析】_哔哩哔哩_bilibili 5分钟讲明白自动驾驶端到端,解释为什么华为智驾并不是遥遥领先 到底什么是端到端自动驾驶系统?为何我会说这是智能驾驶的弯道超车机会?我希望今天用5分钟的时间&…...

Python学习笔记--参数
目录 实参与形参 不定长参数 拆分参数列表 返回值 实参与形参 1. 定义函数时,带默认值的形参必须放在不带默认值的形参后面 下面程序的输出结果是( )。 def StudentInfo(country中国,name): print(%s,%s%(name,country)…...

刷题——大数加法
大数加法_牛客题霸_牛客网 string solve(string s, string t) {if(s.size() < t.size()) return solve(t, s);reverse(s.begin(), s.end());reverse(t.begin(), t.end());string ans;int d 0;//进位制for(int i0; i < s.size(); i){d s[i] - 0;//取得数字值if(i < …...

Pytorch人体姿态骨架生成图像
ControlNet是一个稳定扩散模型,可以复制构图和人体姿势。ControlNet解决了生成想要的确切姿势困难的问题。 Human Pose使用OpenPose检测关键点,如头部、肩膀、手的位置等。它适用于复制人类姿势,但不适用于其他细节,如服装、发型和…...

前端面试常考的HTML标签知识!!!
语义标签 标签名语义描述header网页头部网页的主要头部区域nav网页导航网页的导航链接区域footer网页底部网页的底部区域aside网页侧边栏网页的侧边栏区域section网页区块网页的独立区块 | article | 网页文章 | 网页的独立文章区域 | 字符实体 作用:在网页中显…...

Oracle触发器
Oracle触发器就是特定事件发生时自动执行的存储过程。 触发器基本使用 基本语法: create [or replace] trigger 触发器名称 alter | before | instead of [insert] [[or] update [of 列1,列2,...]] [[or] delete] on 表名 [referencing {OLD [as] old / NEW [as]…...

GPT-5:未来已来,我们如何共舞于智能新纪元?
GPT-5:未来已来,我们如何共舞于智能新纪元? 在科技日新月异的今天,人工智能(AI)的每一次飞跃都深刻地改变着人类社会的面貌。从AlphaGo击败围棋世界冠军,到GPT系列模型引领自然语言处理&#x…...

2024年6月 青少年机器人技术等级考试理论综合试卷(五级)
202406 青少年等级考试机器人理论真题五级 第 1 题 ESP32 for Arduino,通过引脚2读取按键开关的返回值,电路如下图所示,程序pinMode(2, mode);中,参数mode的值是?( ) A:INPUT B&…...

【Go】 HTTP编程3-路由httprouter
HttpRouter httprouter httprouter是第三方的库,不是go的标准库,使用命令 go get -u github.com/julienschmidt/httprouter ,下载该模块,-u表示如果已经下载但更新到最新版本Router 实现了http.Handler接口,为各种 re…...