PyTorch以及VGG模型
PyTorch以及VGG模型
- PyTorch
- 张量(Tensor)
- 数据集和数据加载器(DATASETS & DATALOADERS)
- 未完待续
- VGG模型
- PyTorch版(加载cifar10数据集)
- cifar10数据集
- 加载数据集
- VGG模型结构
- 训练模型
- 测试模型
- 结果示意图
- Keras(TensorFlow)版
- GPU使用与分配
- 数据导入
- 模型
- 训练并测试模型
- 结果(截取部分)
PyTorch
PyTorch官网
- PyTorch是一个开源的Python机器学习库,基于Torch,用于自然语言处理等应用程序。
- 它是一个基于Python的可续计算包,提供两个高级功能:
1、具有强大的GPU加速的张量计算(如NumPy)
2、包含自动求导系统(自动微分机制)的深度神经网络
张量(Tensor)
- 张量(Tensor),类似于数组和矩阵, 是一种特殊的数据结构。在PyTorch中, 神经网络的输入、输出以及网络的参数等数据, 都是使用张量来进行描述。
- 张量的初始化:
- 由原始数据直接生成
- Numpy与Tensor的相互转换生成
- 根据已有的张量来生成
- 通过指定数据的维度生成
代码如下:
import torch
# 由原始数据直接生成
data = {[1, 2], [3, 4]}
data_t = torch.tensor(data)# Numpy与Tensor的相互转换生成
# 1. Tensor转化为Numpy
ten_data = torch.ones(3)
num_data = t.numpy()
# 2. Numpy转化为Tensor
num_data1 = np.ones(3)
ten_data = torch.from_numpy(n)# 根据已有的张量来生成
data_t1 = torch.ones_like(data_t) # 保留data_t的属性
data_new = torch.rand_like(data_t, dtype=torch.float) # 改变data_t的数据类型(int——>float)# 通过指定数据的维度生成
data_shape = (2,3,)
rand_ten = torch.rand(data_shape)
ones_ten = torch.ones(data_shape)
zeros_ten = torch.zeros(data_shape)
- 张量属性:
- 维度 tensor.shape
- 数据类型 tensor.dtype
- 所存储的设备 tensor.device
- 张量的计算在GPU上进行操作的方法
# 首先判断当前环境GPU是否可用, 如果可以将tensor导入GPU内运行
if torch.cuda.is_available():tensor = tensor.to('cuda')
- 张量的计算:(tensor = torch.ones(4, 4))
索引和切片:tensor[ a : b(行索引), c : d (列索引)]
连接:torch.cat([tensor, tensor], dim=1)
矩阵的乘法:
- y1 = tensor @ tensor,T
- y2 = tensor.matmul(tensor.T)
- y3 = torch.rand_like(tensor)
torch.matmul(tensor, tensor.T, out=y3)
矩阵按元素进行乘积:
- z1 = tensor * tensor
- z2 = tensor.mul(tensor)
- z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)
就地运算(将结果存储到操作数中的运算称为就地运算):
以‘ _ ’后缀表示单元素张量转换:
t_sum = tensor.sum()
t_item = t_sum.item()
数据集和数据加载器(DATASETS & DATALOADERS)
- 引言:用于处理数据样本的代码有时会很凌乱并且难以维护;在理想的情况下,我们希望能够将数据集代码与模型训练代码分离,以提高可读性和模块化性。
- PyTorch本身提供了两种数据原语(data primitives)
(补充说明–原语:原语是在操作系统中调用核心层子程序的指令;一般是指由若干条指令组成的程序段,用来实现某个特定功能,在执行过程中不可被中断。)- torch.utils.data.DataLoader
- torch.utils.data.Dataset
未完待续
VGG模型
PyTorch版(加载cifar10数据集)
cifar10数据集
基本说明:CIFAR10包含了 10 个类别的 RGB 彩色图片,分别为:飞机(airplane)、汽车(automobile)、鸟类(bird )、猫(cat)、鹿(deer)、狗(dog)、蛙类(frog)、马(horse)、船(ship)和卡车(truck);该图像尺寸为32*32大小。
如图所示: data_batch_1-data_batch_5分别包含了5个批次的训练数据,每个批次有10000张训练图片;test_batch包含的是测试数据集,有10000张测试的图片。
加载数据集
''' 定义超参数 '''
batch_size = 256 # 每批数据量的大小'''
transforms.Compose:将几个变换组合在一起
transforms.Normalize:用均值和标准差归一化张量图像--计算公式:output[channel] = (input[channel] - mean[channel]) / std[channel]
RandomHorizontalFlip:以0.5的概率水平翻转给定的PIL图像
transforms.RandomResizedCrop:将PIL图像裁剪成任意大小和纵横比
transforms.ToTensor:转换一个PIL库的图片或者numpy的数组为tensor张量类型;转换从[0,255]->[0,1]
'''''' 数据增强 '''
transform = transforms.Compose([transforms.RandomResizedCrop(32), transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize(mean = [ 0.5, 0.5, 0.5 ],std = [ 0.5, 0.5, 0.5 ]),])'''加载训练集 CIFAR-10 10分类训练集'''
train_dataset = datasets.CIFAR10(root=r"D:\TASK\VGG\DATA\datasets", train=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_dataset = datasets.CIFAR10(root=r"D:\TASK\VGG\DATA\datasets", train=False, transform=transform)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
VGG模型结构
表格示意图:
文字说明:
以VGG16为例由上图可知:在卷积中,卷积核的大小为33,步长为1,padding为1;在池化中,共有五个最大池化,池化窗口为22,步长为2
代码如下:
from torch import nnclass VGG(nn.Module):def __init__(self,num_classes=1000):'''# VGG16继承父类nn.Moudle,即把VGG16的对象self转换成nn.Moudle的对象# nn.Sequential()是nn.module()的容器,用于按顺序包装一组网络层# nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0)# nn.Conv2d是二维卷积方法,nn.Conv2d一般用于二维图像;nn.Conv1d是一维卷积方法,常用于文本数据的处理'''super(VGG, self).__init__()self.features=nn.Sequential(# 第1层卷积 3-->64nn.Conv2d(3,64,kernel_size=3,padding=1),nn.BatchNorm2d(64), # 批归一化操作,为了加速神经网络的收敛过程以及提高训练过程中的稳定性,用于防止梯度消失或梯度爆炸;参数为卷积后输出的通道数;nn.ReLU(True),# 第2层卷积 64-->64nn.Conv2d(64,64,kernel_size=3,padding=1),nn.BatchNorm2d(64),nn.ReLU(True),# 第3层池化 图像大小缩小1/2nn.MaxPool2d(kernel_size=2,stride=2),# 第4层卷积 64-->128nn.Conv2d(64, 128, kernel_size=3, padding=1),nn.BatchNorm2d(128),nn.ReLU(True),# 第5层卷积 128-->128nn.Conv2d(128,128,kernel_size=3,padding=1),nn.BatchNorm2d(128),nn.ReLU(True),# 第6层池化 图像大小缩小1/2nn.MaxPool2d(kernel_size=2, stride=2),# 第7层卷积 128-->256nn.Conv2d(128,256,kernel_size=3,padding=1),nn.BatchNorm2d(256),nn.ReLU(True),# 第8层卷积 256-->256nn.Conv2d(256,256,kernel_size=3,padding=1),nn.BatchNorm2d(256),nn.ReLU(True),# 第9层卷积 256-->256nn.Conv2d(256, 256, kernel_size=3, padding=1),nn.BatchNorm2d(256),nn.ReLU(True),# 第10层池化 图像大小缩小1/2nn.MaxPool2d(kernel_size=2, stride=2),# 第11层卷积 256-->512nn.Conv2d(256, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),# 第12层卷积 512-->512nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),# 第13层卷积 512-->512nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),# 第14层池化 图像大小缩小1/2nn.MaxPool2d(kernel_size=2, stride=2),# 第15层卷积 512-->512nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),# 第16层卷积 512-->512nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),# 第17层卷积 512-->512nn.Conv2d(512, 512, kernel_size=3, padding=1),nn.BatchNorm2d(512),nn.ReLU(True),# 第18层池化 图像大小缩小1/2nn.MaxPool2d(kernel_size=2, stride=2),)self.classifier=nn.Sequential(# 全连接层512-->4096nn.Linear(512,4096),nn.Dropout(),# 全连接层4096-->4096nn.Linear(4096,4096),nn.Dropout(),# 全连接层4096-->1000nn.Linear(4096,num_classes),nn.Dropout())def forward(self,a):out = self.features(a)# 所得数据为二位数据# view功能相当于numpy中resize()的功能,作用:将一个多行的Tensor,拼接成一行(flatten)out = out.view(out.size(0),-1)out = self.classifier(out) # 分类数据为一维数据return outmodule=VGG()
print(module)use_gpu = torch.cuda.is_available() # 判断是否有GPU加速
if use_gpu:model = model.cuda()
训练模型
''' 定义超参数 '''
learning_rate = 1e-3 # 学习率
num_epoches = 50 # 遍历训练集的次数''' 定义loss和optimizer '''
# 交叉熵损失(包括softmax运算和交叉熵损失计算的函数)
criterion = nn.CrossEntropyLoss()
# SGD优化器(随机梯度下降算法)
optimizer = optim.SGD(model.parameters(), lr=learning_rate)''' 训练 '''
for epoch in range(num_epoches):print('*' * 25, 'epoch {}'.format(epoch + 1), '*' * 25) running_loss = 0.0running_acc = 0.0for i, data in tqdm(enumerate(train_loader, 1)): # 遍历img, label = data# cudaif use_gpu:img = img.cuda()label = label.cuda()# Variable 变量img = Variable(img)label = Variable(label)# 向前传播# with torch.no_grad():out = model(img)loss = criterion(out, label) # 计算交叉熵损失running_loss += loss.item() * label.size(0)_, pred = torch.max(out, 1) # 预测最大值所在的位置标签,维度为1num_correct = (pred == label).sum() # 预测正确的数目accuracy = (pred == label).float().mean()running_acc += num_correct.item() # 统计预测正确的总数# 向后传播optimizer.zero_grad()loss.backward()optimizer.step()print('Finish {} epoch, Loss: {:.6f}, Acc: {:.6f}'.format(epoch + 1, running_loss / (len(train_dataset)), running_acc / (len(train_dataset))))
测试模型
''' 模型评估 '''model.eval()eval_loss = 0eval_acc = 0''' 测试模型 '''for data in test_loader: img, label = dataif use_gpu:img = Variable(img).cuda() # Variable将其转换为变量label = Variable(label).cuda()else:img = Variable(img)label = Variable(label)out = model(img)loss = criterion(out, label)eval_loss += loss.item() * label.size(0)_, pred = torch.max(out, 1)num_correct = (pred == label).sum()eval_acc += num_correct.item()print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len(test_dataset)), eval_acc / (len(test_dataset))))print()# 对模型进行保存
torch.save(model.state_dict(), './cnn.pth')
结果示意图
************************* epoch 45 *************************
196it [00:43, 4.48it/s]
Finish 45 epoch, Loss: 0.090376, Acc: 0.978320
0it [00:00, ?it/s]Test Loss: 1.095920, Acc: 0.743900************************* epoch 46 *************************
196it [00:43, 4.48it/s]
Finish 46 epoch, Loss: 0.023772, Acc: 0.996000
0it [00:00, ?it/s]Test Loss: 1.250700, Acc: 0.736100************************* epoch 47 *************************
196it [00:44, 4.41it/s]
Finish 47 epoch, Loss: 0.013472, Acc: 0.998060
0it [00:00, ?it/s]Test Loss: 1.363737, Acc: 0.739100************************* epoch 48 *************************
196it [00:44, 4.44it/s]
Finish 48 epoch, Loss: 0.008261, Acc: 0.999160
0it [00:00, ?it/s]Test Loss: 1.361765, Acc: 0.745700************************* epoch 49 *************************
196it [00:43, 4.48it/s]
Finish 49 epoch, Loss: 0.005402, Acc: 0.999560
0it [00:00, ?it/s]Test Loss: 1.441942, Acc: 0.744200************************* epoch 50 *************************
196it [00:43, 4.49it/s]
Finish 50 epoch, Loss: 0.003578, Acc: 0.999760
Test Loss: 1.482398, Acc: 0.745400
Keras(TensorFlow)版
GPU使用与分配
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" # 按照PCI_BUS_ID顺序从0开始排列GPU设备
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # 设置当前使用的GPU设备仅为0号设备 设备名称为'/gpu:0'
gpus = tf.config.experimental.list_physical_devices("GPU") # 将 GPU 的显存使用策略设置为 “仅在需要时申请显存空间”
if gpus:try:for gpu in gpus:tf.config.experimental.set_memory_growth(gpu,True)except RuntimeError as e:print(e)exit(1) # 有错误时退出
数据导入
- dataload.py文件:读取数据(数据的预处理命令的定义)
from __future__ import absolute_import
from __future__ import division
from __future__ import print_functionfrom tensorflow.keras import backend as K
import numpy as np
import osimport sys
from six.moves import cPickledef load_batch(fpath, label_key='labels'):"""Internal utility for parsing CIFAR data.# Argumentsfpath: path the file to parse.label_key: key for label data in the retrievedictionary.# ReturnsA tuple `(data, labels)`."""with open(fpath, 'rb') as f:if sys.version_info < (3,):d = cPickle.load(f)else:d = cPickle.load(f, encoding='bytes')# decode utf8d_decoded = {}for k, v in d.items():d_decoded[k.decode('utf8')] = vd = d_decodeddata = d['data']labels = d[label_key]data = data.reshape(data.shape[0], 3, 32, 32)return data, labelsdef load_data(ROOT):""" 加载CIFAR1数据集# ReturnsTuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`."""path = ROOTnum_train_samples = 50000x_train = np.empty((num_train_samples, 3, 32, 32), dtype='uint8')y_train = np.empty((num_train_samples,), dtype='uint8')for i in range(1, 6):fpath = os.path.join(path, 'data_batch_' + str(i))(x_train[(i - 1) * 10000: i * 10000, :, :, :],y_train[(i - 1) * 10000: i * 10000]) = load_batch(fpath)fpath = os.path.join(path, 'test_batch')x_test, y_test = load_batch(fpath)y_train = np.reshape(y_train, (len(y_train), 1))y_test = np.reshape(y_test, (len(y_test), 1))if K.image_data_format() == 'channels_last':x_train = x_train.transpose(0, 2, 3, 1)x_test = x_test.transpose(0, 2, 3, 1)return (x_train, y_train), (x_test, y_test)
- 数据导入
(x_train, y_train), (x_test, y_test) = load_data('D:\TASK\VGG\DATA\datasets\cifar-10-batches-py')
模型
代码如下:
''' 库的导入 '''
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Conv2D,MaxPooling2D
from tensorflow.keras.layers import Flatten,Dense,Dropout''' 模型构建 '''
model = Sequential()# 卷积层
model.add(Conv2D(64,(3,3), strides = (1,1), input_shape = (32,32,3), padding = 'same', activation = 'relu'))
model.add(Conv2D(64,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(MaxPooling2D((2,2), strides = (2,2)))model.add(Conv2D(128,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(Conv2D(128,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(MaxPooling2D((2,2), strides = (2,2)))model.add(Conv2D(256,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(Conv2D(256,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(Conv2D(256,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(MaxPooling2D((2,2), strides = (2,2)))model.add(Conv2D(512,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(Conv2D(512,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(Conv2D(512,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(MaxPooling2D((2,2), strides = (2,2)))model.add(Conv2D(512,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(Conv2D(512,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(Conv2D(512,(3,3), strides = (1,1), padding = 'same', activation = 'relu'))
model.add(MaxPooling2D((2,2), strides = (2,2)))# 全连接层
model.add(Flatten())
model.add(Dense(4096, activation = 'relu'))
model.add(Dense(4096, activation = 'relu'))
model.add(Dense(1000, activation = 'softmax'))model.summary() # 对模型进行展示,即输出模型的参数情况''' 定义优化器 '''
model.compile(optimizer=keras.optimizers.Adam(0.0001), # 优化器,其中0.0001为学习率loss=keras.losses.sparse_categorical_crossentropy, # 损失函数metrics=["accuracy"]) # 标注网络评价指标 "accuracy" : y_ 和 y 都是数值,如y_ = [1] y = [1] 其中y_为真实值,y为预测值
模型展示:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 32, 32, 64) 1792
_________________________________________________________________
conv2d_1 (Conv2D) (None, 32, 32, 64) 36928
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 16, 16, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 16, 16, 128) 73856
_________________________________________________________________
conv2d_3 (Conv2D) (None, 16, 16, 128) 147584
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 8, 8, 128) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 8, 8, 256) 295168
_________________________________________________________________
conv2d_5 (Conv2D) (None, 8, 8, 256) 590080
_________________________________________________________________
conv2d_6 (Conv2D) (None, 8, 8, 256) 590080
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 4, 4, 256) 0
_________________________________________________________________
conv2d_7 (Conv2D) (None, 4, 4, 512) 1180160
_________________________________________________________________
conv2d_8 (Conv2D) (None, 4, 4, 512) 2359808
_________________________________________________________________
conv2d_9 (Conv2D) (None, 4, 4, 512) 2359808
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 2, 2, 512) 0
_________________________________________________________________
conv2d_10 (Conv2D) (None, 2, 2, 512) 2359808
_________________________________________________________________
conv2d_11 (Conv2D) (None, 2, 2, 512) 2359808
_________________________________________________________________
conv2d_12 (Conv2D) (None, 2, 2, 512) 2359808
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 1, 1, 512) 0
_________________________________________________________________
flatten (Flatten) (None, 512) 0
_________________________________________________________________
dense (Dense) (None, 4096) 2101248
_________________________________________________________________
dense_1 (Dense) (None, 4096) 16781312
_________________________________________________________________
dense_2 (Dense) (None, 1000) 4097000
=================================================================
Total params: 37,694,248
Trainable params: 37,694,248
Non-trainable params: 0
_________________________________________________________________
训练并测试模型
''' 数据可视化 '''
Tensorboard = TensorBoard(log_dir="logs", histogram_freq=1)
# histogram_freq:对于模型中各个层计算激活值和模型权重直方图的频率
# log_dir: 用来保存被 TensorBoard 分析的日志文件的文件名。
history = model.fit(x_train, y_train,epochs=50, callbacks=[Tensorboard],batch_size=256,validation_data=(x_test, y_test))
'''
元组 (x_val,y_val) 用来评估损失,以及在每轮结束时的任何模型度量指标;模型将不会在这个数据上进行训练。
'''
结果(截取部分)
PyTorch以及VGG模型相关推荐
- 【小白学PyTorch】6.模型的构建访问遍历存储(附代码)
<<小白学PyTorch>> 小白学PyTorch | 5 torchvision预训练模型与数据集全览 小白学PyTorch | 4 构建模型三要素与权重初始化 小白学PyT ...
- Pytorch两种模型保存方式
以字典方式保存,更容易解析和可视化 Pytorch两种模型保存方式 大黑_7e1b关注 2019.02.12 17:49:35字数 13阅读 5,907 只保存模型参数 # 保存 torch.save ...
- Pytorch学习 - 保存模型和重新加载
Pytorch学习 - 保存和加载模型 1. 3个函数 2. 模型不同后缀名的区别 3. 保存和重载模型 参考资料: Pytorch官方文档链接 某博客 1. 3个函数 torch.save() : ...
- 【pytorch速成】Pytorch图像分类从模型自定义到测试
文章首发于微信公众号<与有三学AI> [pytorch速成]Pytorch图像分类从模型自定义到测试 前面已跟大家介绍了Caffe和TensorFlow,链接如下. [caffe速成]ca ...
- 第18课:项目实战——利用 PyTorch 构建 RNN 模型
上一篇,我们主要介绍了基本的 RNN 模型和 LSTM.本文将通过一个实战项目带大家使用 PyTorch 搭建 RNN 模型. 本项目将构建一个 RNN 模型,来对 MNIST 手写数据集进行分类.可 ...
- [Python图像识别] 四十八.Pytorch构建Faster-RCNN模型实现小麦目标检测
该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...
- (pytorch-深度学习系列)pytorch构造深度学习模型-学习笔记
pytorch构造深度学习模型 1. 通过继承module类的方式来构造模型 Module类是nn模块里提供的一个模型构造类,是所有神经网络模块的基类. 可以继承基类并重构 __init()__函数和 ...
- PyTorch导出JIT模型并用C++ API libtorch调用
PyTorch导出JIT模型并用C++ API libtorch调用 本文将介绍如何将一个 PyTorch 模型导出为 JIT 模型并用 PyTorch 的 C++API libtorch运行这个模型 ...
- python与机器学习(七)上——PyTorch搭建LeNet模型进行MNIST分类
任务要求:利用PyTorch框架搭建一个LeNet模型,并针对MNIST数据集进行训练和测试. 数据集:MNIST 导入: import torch from torch import nn, opt ...
- pytorch中获取模型参数
原文链接:pytorch中获取模型参数:state_dict和parameters两个方法的差异比较_造未来-CSDN博客 一.本文的模型案例 代码如下: import torch import to ...
最新文章
- META Header
- php 预订义变量,预约义变量 PHP
- .NET笔试题集(一)
- 删除DataTable中列重复的行
- 纯干货!文字识别在高德地图数据生产中的演进
- MX130+python3.7.6+CUDA 10.0+CUDNN 7.4.2+TensorFlow-gpu安装
- Fiddle:使用断点:bpu,bpafter
- 告诉我们您想要什么,我们将做到:消费者驱动的合同测试消息传递
- uniapp光标自动定义到文本框_word如何自动生成毕业论文目录!
- 使用Putty密钥认证机制远程登录Linux
- 腾讯开工日1.5亿美元领投Reddit,美国贴吧最新估值30亿美元
- flutter实现Icon可以用Image替换
- SWF文件反编译调试记录
- php中表格的高度怎么改,ppt表格行高调整不了怎么办
- 极米H5多少流明?采用新亮度标准的极米H5怎么样?性价比高吗?
- Cubieboard2折腾手记(一)
- objdump指令 elf文件转成lst文件
- 关于ligerui grid分页checkbox绑定问题
- 计算机图片怎么截图快捷键,电脑截图快捷键四种截屏方式,笔记本电脑如何截屏截图?...
- 华为交换机升级包及补丁验证完整性
热门文章
- Linux Mint 笔记本亮度调节总结
- ubuntu18.04 eclipse +sdcc开发stm8l152 并且单步调试
- win10迁移C盘Administrator目录
- hdu4415 Assassin’s Creed (贪心)
- Flume Kafka Channel使用案例
- java 裁剪图片_java实现的图片裁剪功能示例
- 使用scrapy框架爬虫实战
- 台式计算机usb口不能用,电脑usb接口没反应是什么原因?电脑usb接口没反应解决方法...
- 关于JAVA开发小游戏如何做读档和存档功能的这件事
- 苹果手机怎么验证app_苹果序列号查询 未验证怎么办?