[深度学习实战]基于PyTorch的深度学习实战(下)

2023-10-29


PyTorch——开源的Python机器学习库

一、前言

  首先感谢所有点开本文的朋友们!基于PyTorch的深度学习实战可能要告一段落了。本想着再写几篇关于PyTorch神经网络深度学习的文章来着,可无奈项目时间紧任务重,要求短时间内出图并做好参数拟合。所以只得转战Matlab编程,框架旧就旧吧,无所谓了 (能出结果就行)
  往期回顾:
[深度学习实战]基于PyTorch的深度学习实战(上)[变量、求导、损失函数、优化器]

[深度学习实战]基于PyTorch的深度学习实战(中)[线性回归、numpy矩阵的保存、模型的保存和导入、卷积层、池化层]


二、Mnist手写数字图像识别

  一个典型的神经网络的训练过程大致分为以下几个步骤:
  (1)首先定义神经网络的结构,并且定义各层的权重参数的规模和初始值
  (2)然后将输入数据分成多个批次输入神经网络
  (3)将输入数据通过整个网络进行计算
  (4)每次迭代根据计算结果和真实结果的差值计算损失
  (5)根据损失对权重参数进行反向求导传播
  (6)更新权重值更新过程使用下面的公式
  weight = weight + learning_rate * gradient。其中 weight 是上一次的权重值,learning_rate 是学习步长,gradient 是求导值
  下面我们还是以经典的图像识别卷积网络作为例子来学习 pytorch 的用法。选择一个较小的数据集进行训练,这里我们选择 mnist 手写识别数据集,该数据集是 0-9 个数字的训练数据和测试数据,训练数据 60000 张图片,测试数据 10000 张图片。每张图片是 28×28 像素大小的单通道黑白图片,这样读到内存数据组就是 28 * 28 * 1 大小。这里的 28 * 28 是宽度和高度的像素数量,1 是图像通道数据(如果是彩色图像就是 3 道路,内存数据为 28 * 28 * 3 大小)。
  我们先看看样本图像的模样:
在这里插入图片描述
  好,下一步我们构建一个简单的卷积神经网络模型这个模型的输入是图片,输出是 0-9 的数字,这是一个典型的监督式分类神经网络

2.1 加载数据

  这里我们不打算下载原始的图像文件然后通过 opencv 等图像库读取到数组而是直接下载中间数据。当然读者也可以下载原始图像文件从头开始装载数据,这样对整个模型会有更深刻的体会。
  我们用 mnist 数据集作例子,下载方法有两种:

2.1.1 下载地址

  http://yann.lecun.com/exdb/mnist/。一共四个文件:
  train-images-idx3-ubyte.gz: training set images (9912422 bytes)
  train-labels-idx1-ubyte.gz: training set labels (28881 bytes)
  t10k-images-idx3-ubyte.gz: test set images (1648877 bytes)
  t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes)
  这些文件中是已经处理过的数组数据,通过numpy的相关方法读取到训练数据集和测试数据集数组中注意调用 load_mnist 方法之前先解压上述四个文件

from __future__ import print_function
import os
import struct
import numpy as np
def load_mnist(path, kind='train'):
labels_path = os.path.join(path, '%s-labels.idx1-ubyte' % kind)
images_path = os.path.join(path, '%s-images.idx3-ubyte' % kind)
with open(labels_path, 'rb') as lbpath:
magic, n = struct.unpack('>II', lbpath.read(8))
labels = np.fromfile(lbpath, dtype=np.uint8)
with open(images_path, 'rb') as imgpath:
magic, num, rows, cols = struct.unpack(">IIII", imgpath.read(16))
images = np.fromfile(imgpath, dtype=np.uint8).reshape(len(labels), 784)
return images, labels
X_train, y_train = load_mnist('./data', kind='train')
print('Rows: %d, columns: %d' % (X_train.shape[0], X_train.shape[1]))
X_test, y_test = load_mnist('./data', kind='t10k')
print('Rows: %d, columns: %d' % (X_test.shape[0], X_test.shape[1]))

  显示结果

D:\AI>python mnist_cnn.py
Rows: 60000, columns: 784
Rows: 10000, columns: 784

  我们看到训练数据的行数是 60000,表示 60000 张图片,列是 784,表示 28281=784 个像素,测试数据是 10000 张图片,在后面构建卷积模型时,要先将 784 个像素的列 reshape 成 28281 维度
  例如:

image1 = X_train[1]
image1 = image1.astype('float32')
image1 = image1.reshape(28,28,1)

  我们还可以将这些图像数组导出为 jpg 文件,比如下面的代码:

import cv2
cv2.imwrite('1.jpg',image1)

  当前目录下的 1.jpg 文件都是我们导出的图像文件了。
  图像的显示:

import cv2
import numpy as np
img = cv2.imread("C:\lena.jpg")
cv2.imshow("lena",img)
cv2.waitKey(10000)

2.1.2 用 numpy 读取 mnist.npz

  可以直接从亚马逊下载文件:
  https://s3.amazonaws.com/imgdatasets/mnist.npz
  Mnist.npz 是一个 numpy 数组文件。如果下载的是 mnist.npz.gz 文件,则用 gunzip mnist.npz.gz 先解压成 mnist.npz,然后再处理也可以调用 keras 的方法来下载

from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

  通过 mnist.load_data() 下载的 mnist.npz 会放在当前用户的 .keras 目录中。路径名称:
  ~/.keras/datasets/mnist.npz
  然后调用 numpy 来加载 mnist.npz。
  示例代码:

import numpy as np
class mnist_data(object):
def load_npz(self,path):
f = np.load(path)
for i in f:
print i
x_train = f['trainInps']
y_train = f['trainTargs']
x_test = f['testInps']
y_test = f['testTargs']
f.close()
return (x_train, y_train), (x_test, y_test)
a = mnist_data()
(x_train, y_train), (x_test, y_test) = a.load_npz('D:/AI/torch/data/mnist.npz')
print ("train rows:%d,test rows:%d"% (x_train.shape[0], x_test.shape[0]))
print("x_train shape",x_train.shape)
print("y_train shape",y_train.shape )

  结果:
在这里插入图片描述
  一共 60000 张训练图片,10000 张测试图片。训练图像的大小 784 个像素,也就是 1 通道的 28*28 的手写图片。标签是长度为 10 的 (0,1) 向量,表示 0-9 是个数字。例如数字 1 就表示为 [0,1,0,0,0,0,0,0,0,0]。
  让我们打印出第一张图片的截图和标签。代码如下:

tt=x_train[1]
tt=tt.astype('float32')
image = tt.reshape(28,28,1)
cv2.imwrite("001.png",image)
print("tt label:",y_train[1])

在这里插入图片描述
在这里插入图片描述
  标签为 [0,0,0,1,0,0,0,0,0,0]。


2.2 定义卷积模型

  这一步我们定义自己的卷积模型,对于 28 * 28 的数组,我们定义 (5,5) 的卷积核大小比较合适,卷积核的大小可根据图像大小灵活设置,比如 (3,3),(5,5),(9,9)等。一般卷积核的大小是奇数
  输入数据首先连接 1 个卷积层加 1 个池化层,conv1 和 pool1,假设我们定义 conv1 的神经元数目为 10,卷积核大小 (5,5),定义 pool1 的大小 (2,2),意思将 2 * 2区域共 4 个像素统计为 1 个像素这样这层数据量减少 4 倍。这时候输出图像大小为 (28-5+1)/2=12。输出数据维度(10,12,12)。
  接着再来一次卷积池化,连接 1 个卷积层加 1 个池化层,conv2 和 pool2,假设我们定义 conv2 的神经元数目为 20,卷积核大小 (5,5),定义pool2的大小 (2,2),意思将 2*2 区域共 4 个像素统计为 1 个像素,这样这层数据量减少 4 倍。这时候输出图像大小为 (12-5+1)/2=4。输出数据维度 (20,4,4)。
  然后接一个 dropout 层,设置 dropout=0.2,随机抛弃部分数据
  最后连续接两个全连接层,第一个全连接层 dense1 输入维度 20 * 4 * 4,输出 320,第二个全连接层 dense1 输入维度 60,输出 10。
  模型定义的 pytorch 代码如下

class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
self.conv2_drop = nn.Dropout2d()
self.fc1 = nn.Linear(320, 60)
self.fc2 = nn.Linear(60, 10)
def forward(self, x):
x = F.relu(F.max_pool2d(self.conv1(x), 2))
x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
x = x.view(-1, 320)
x = F.relu(self.fc1(x))
x = F.dropout(x, training=self.training)
x = self.fc2(x)
return F.log_softmax(x)
model = Net()
print(model)

  注解:nn.Conv2d(1, 10, kernel_size=5) 是指将 1 通道的图像数据的输入卷积成 10 个神经元这 1 个通道跟 10 个神经元都建立连接,然后神经网络对每个连接计算出不同的权重值,某个神经元上的权重值对原图卷积来提取该神经元负责的特征这个过程是神经网络自动计算得出的
  那么 nn.Conv2d(10, 20, kernel_size=5) 是指将 10 通道的图像数据的输入卷积成 20 个神经元,同样的,这 10 个通道会和 20 个神经元的每一个建立连接,那么10 个通道如何卷积到 1 个通道呢?一般是取 10 个通道的平均值作为最后的结果
  执行该脚本,将卷积模型的结构打印出来

[root@iZ25ix41uc3Z ai]# python mnist_torch.py
Net (
(conv1): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1))
(conv2_drop): Dropout2d (p=0.5)
(fc1): Linear (320 -> 50)
(fc2): Linear (50 -> 10)
)

2.3 开始训练

  数据准备好模型建立好,下面根据神经网络的三部曲,就是选择损失函数和梯度算法对模型进行训练了
  损失函数通俗讲就是计算模型的计算结果和真实结果之间差异性的函数典型的如距离的平方和再开平方,对于图像分类来说,我们取的损失函数是:

F.log_softmax(x)

  在神经网络的训练过程中,我们使用 loss.backward() 来反向传递修正反向修正就是根据计算和真实结果的差值(就是损失)来反向逆传播修正各层的权重参数,修正之后的结果保存在 .grad 中,因此每轮迭代执行 loss.backward() 的时候要先对 .grad 清零。

model.zero_grad()
print('conv1.bias.grad before backward')
print(model.conv1.bias.grad)
loss.backward()
print('conv1.bias.grad after backward')
print(model.conv1.bias.grad)

  优化算法一般是指迭代更新权重参数的梯度算法,这里我们选择随机梯度算法 SGD
  SGD 的算法如下:

weight = weight - learning_rate * gradient

  可以用一段简单的 python 脚本模拟这个 SGD 的过程

learning_rate = 0.01
for f in model.parameters():
f.data.sub_(f.grad.data * learning_rate)

  pytorch 中含有其他的优化算法,如 Nesterov-SGD, Adam, RMSProp 等。
  它们的用法和 SGD 基本类似,这里就不一一介绍了。
  训练代码如下:

import torch.optim as optim
input = Variable(torch.randn(1, 1, 32, 32))
out = model(input)
print(out)
# create your optimizer
optimizer = optim.SGD(model.parameters(), lr=0.01)
# in your training loop:
optimizer.zero_grad() # zero the gradient buffers
output = model(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # Does the update

2.4 完整代码

  最后的代码如下所示,这里我们做了一点修改,每次迭代完会将模型参数保存到文件,下次再次执行脚本会自动加载上次迭代后的数据。整个完整的代码如下:

'''
Trains a simple convnet on the MNIST dataset.
'''
from __future__ import print_function
import os
import struct
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
def load_mnist(path, kind='train'):
"""Load MNIST data from `path`"""
labels_path = os.path.join(path, '%s-labels.idx1-ubyte' % kind)
images_path = os.path.join(path, '%s-images.idx3-ubyte' % kind)
with open(labels_path, 'rb') as lbpath:
magic, n = struct.unpack('>II', lbpath.read(8))
labels = np.fromfile(lbpath, dtype=np.uint8)
with open(images_path, 'rb') as imgpath:
magic, num, rows, cols = struct.unpack(">IIII", imgpath.read(16))
images = np.fromfile(imgpath, dtype=np.uint8).reshape(len(labels), 784)
return images, labels
X_train, y_train = load_mnist('./data', kind='train')
print("shape:",X_train.shape)
print('Rows: %d, columns: %d' % (X_train.shape[0], X_train.shape[1]))
X_test, y_test = load_mnist('./data', kind='t10k')
print('Rows: %d, columns: %d' % (X_test.shape[0], X_test.shape[1]))
batch_size = 100
num_classes = 10
epochs = 2
# input image dimensions
img_rows, img_cols = 28, 28
x_train= X_train
x_test=X_test
if 'channels_first' == 'channels_first':
x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')
num_samples=x_train.shape[0]
print("num_samples:",num_samples)
'''
build torch model
'''
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
self.conv2_drop = nn.Dropout2d()
self.fc1 = nn.Linear(320, 50)
self.fc2 = nn.Linear(50, 10)
def forward(self, x):
x = F.relu(F.max_pool2d(self.conv1(x), 2))
x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
x = x.view(-1, 320)
x = F.relu(self.fc1(x))
x = F.dropout(x, training=self.training)
x = self.fc2(x)
return F.log_softmax(x)
model = Net()
if os.path.exists('mnist_torch.pkl'):
model = torch.load('mnist_torch.pkl')
print(model)
'''
trainning
'''
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
#loss=torch.nn.CrossEntropyLoss(size_average=True)
def train(epoch,x_train,y_train):
num_batchs = num_samples/ batch_size
model.train()
for k in range(num_batchs):
start,end = k*batch_size,(k+1)*batch_size
data, target = Variable(x_train[start:end],requires_grad=False), Variable(y_train[optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
if k % 10 == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, k * len(data), num_samples,
100. * k / num_samples, loss.data[0]))
torch.save(model, 'mnist_torch.pkl')
'''
evaludate
'''
def test(epoch):
model.eval()
test_loss = 0
correct = 0
if 2>1:
data, target = Variable(x_test, volatile=True), Variable(y_test)
output = model(data)
test_loss += F.nll_loss(output, target).data[0]
pred = output.data.max(1)[1] # get the index of the max log-probability
correct += pred.eq(target.data).cpu().sum()
test_loss = test_loss
test_loss /= len(x_test) # loss function already averages over batch size
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(x_test),
100. * correct / len(x_test)))
x_train=torch.from_numpy(x_train).float()
x_test=torch.from_numpy(x_test).float()
y_train=torch.from_numpy(y_train).long()
y_test=torch.from_numpy(y_test).long()
for epoch in range(1,epochs):
train(epoch,x_train,y_train)
test(epoch)

2.5 验证结果

  2 次迭代后:Test set: Average loss: 0.3419, Accuracy: 9140/10000 (91%)
  3 次迭代后:Test set: Average loss: 0.2362, Accuracy: 9379/10000 (94%)
  4 次迭代后:Test set: Average loss: 0.2210, Accuracy: 9460/10000 (95%)
  5 次迭代后:Test set: Average loss: 0.1789, Accuracy: 9532/10000 (95%)
  顺便说一句,pytorch 的速度比 keras 确实要快很多,每次迭代几乎 1 分钟内就完成了,确实很不错!


2.6 修改参数

  我们把卷积层的神经元个数重新设置一下,第一层卷积加到 32 个,第二层卷积神经元加到 64 个。则新的模型为下面的组织:

{
(conv1): Conv2d(1, 32, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1))
(conv2_drop): Dropout2d (p=0.5)
(fc1): Linear (1024 -> 100)
(fc2): Linear (100 -> 10)
)

  然后同样的步骤我们跑一遍看看结果如何,这次明显慢了很多,但看的出来准确度也提高了一些:
  第 1 次迭代:Test set: Average loss: 0.3159, Accuracy: 9038/10000 (90%)
  第 2 次迭代:Test set: Average loss: 0.1742, Accuracy: 9456/10000 (95%)
  第 3 次迭代:Test set: Average loss: 0.1234, Accuracy: 9608/10000 (96%)
  第 4 次迭代:Test set: Average loss: 0.1009, Accuracy: 9694/10000 (97%)


三、后记

  至此,我们已经完成了机器学习中的深度学习的大部分实用知识点。其实,我这里都是演示已经跑通的程序,而在修改程序配置环境等等这些“绕弯路”的经历才更能锻炼人。基于PyTorch的深度学习实战还会有个补充篇放出,补充RNN和LSTM原理相关,作为《基于PyTorch的深度学习实战》这个方向的最后一篇。稍后见!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[深度学习实战]基于PyTorch的深度学习实战(下) 的相关文章

  • Django:模拟模型上的字段

    如何将模拟对象分配给该模型上的用户字段 无论如何都要绕过 SomeModel user 必须是 User 实例 检查吗 class SomeModel models Model user models ForeignKey User 我不会
  • Python setuptools:如何在 setup.py 中添加私有存储库 (gitlab)?

    我上传了 2 个包 它们位于我的 gitlab 存储库中 如果我想使用 pip 将它们安装在我的系统中 这很容易 因为 gitlab 可以帮助您 https docs gitlab com ee user packages pypi rep
  • 如何使用 pyinstaller 包含文件?

    我也使用 tkinter 使用 python 3 7 编写了一个程序 由于我使用的是外部图片 因此当我将所有内容编译为一个 exe 时 我需要包含它们 我试过做 add data bg png files 但我仍然收到此错误 tkinter
  • Python有条件求解时滞微分方程

    我在用dde23 of pydelay包来求解延迟微分方程 我的问题 如何有条件地编写方程 例如目标方程有两个选项 when x gt 1 dx dt 0 25 x t tau 1 0 pow x t tau 10 0 0 1 x othe
  • Kivy - 文本换行工作错误

    我正在尝试在 Kivy 1 8 0 应用程序中换行文本 当没有太多文字时 一切正常 但如果文本很长并且窗口不是很大 它只是剪切文本 这是示例代码 vbox BoxLayout orientation vertical size hint y
  • Python 2.7 将比特币私钥转换为 WIF 私钥

    作为一名编码新手 我刚刚完成了教程 教程是这样的 https www youtube com watch v tX XokHf nI https www youtube com watch v tX XokHf nI 我想用 1 个易于阅读
  • Jupyter Notebooks 不显示进度条

    我正在尝试在 Jupyter 笔记本中显示进度条 这是一台新电脑 我通常做的事情似乎不起作用 from tqdm import tqdm notebook example iter 1 2 3 4 5 for rec in tqdm not
  • 如何使用显式引用转储 YAML?

    递归引用非常适合ruamel yaml or pyyaml ruamel yaml dump ruamel yaml load A A id001 id001 然而 它 显然 不适用于普通引用 ruamel yaml dump ruamel
  • Tweepy StreamListener 到 CSV

    我是 python 新手 我正在尝试开发一个应用程序 使用 Tweepy 和 Streaming API 从 Twitter 检索数据并将数据转换为 CSV 文件 问题是此代码不会创建输出 CSV 文件 也许是因为我应该将代码设置为在实现例
  • WindowsError:[错误 126] 使用 ctypes 加载操作系统时

    python代码无法在Windows 7平台上运行 def libSO lib ctypes cdll LoadLibrary ConsoleApplication2 so lib cfoo2 1 3 当我尝试运行它时 得到来自python
  • Apache Spark 中的高效字符串匹配

    我使用 OCR 工具从屏幕截图中提取文本 每个大约 1 5 句话 然而 当手动验证提取的文本时 我注意到时不时会出现一些错误 鉴于文本 你好 我真的很喜欢 Spark 我注意到 1 像 I 和 l 这样的字母被 替换 2 表情符号未被正确提
  • 与 while 循环一样,如何跳过 for 循环中的步骤?

    我尝试像 while 循环一样跳过 for 循环中的几个步骤 在 while 循环中 步骤根据特定条件进行调整 如下面的代码所示 i 0 while i lt 10 if i 3 i 5 else print i i i 1 result
  • 无法在 python 3.8 上将带有 webapp 的 python 部署到 azure

    我正在尝试使用部署一个测试项目Flask使用以下方法将框架迁移到 Azure 云中Azure CLI https learn microsoft com en us azure app service containers quicksta
  • 如何使用 Keras ImageDataGenerator 预测单个图像?

    我已经训练 CNN 对图像进行 3 类分类 在训练模型时 我使用 keras 的 ImageDataGenerator 类对图像应用预处理功能并重新缩放它 现在我的网络在测试集上训练得非常准确 但我不知道如何在单图像预测上应用预处理功能 如
  • 处理大文件的最快方法?

    我有多个 3 GB 制表符分隔文件 每个文件中有 2000 万行 所有行都必须独立处理 任何两行之间没有关系 我的问题是 什么会更快 逐行阅读 with open as infile for line in infile 将文件分块读入内存
  • 在 virtualenvwrapper 中激活环境

    我安装了virtualenv and virtualenvwrapper用这个命令我创建了一个环境 mkvirtualenv cv 它有效 创建后我就处于新环境中 现在我重新启动了我的电脑 我想activate又是那个环境 但是怎么样 我使
  • 更改 Python Cmd 模块处理自动完成的方式

    我有一个 Cmd 控制台 设置为自动完成 Magic the Gathering 收藏管理系统的卡牌名称 它使用文本参数在数据库中查询卡片 并使用结果自动完成 建议卡片 然而 这些卡片名称有多个单词 Cmd 会从last到行尾的空间 例如
  • Python 通过从现有 csv 文件中过滤选定的行来写入新的 csv 文件

    只是一个问题 我试图将 csv 文件中的选定行写入新的 csv 文件 但出现错误 我试图读取的 test csv 文件是这样的 两列 2013 9 1 2013 10 2 2013 11 3 2013 12 4 2014 1 5 2014
  • 在 Django shell 会话期间获取 SQL 查询计数

    有没有办法打印 Django ORM 在 Django shell 会话期间执行的原始 SQL 查询的数量 Django 调试工具栏已经提供了此类信息 例如 5 QUERIES in 5 83MS但如何从 shell 中获取它并不明显 您可
  • 缓存 Flask-登录 user_loader

    我有这个 login manager user loader def load user id None return User query get id 在我引入 Flask Principal 之前它运行得很好 identity loa

随机推荐

  • 【贪心算法】哈夫曼编码问题

    问题描述 哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法 其压缩率通常在20 90 之间 哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0 1串表示各字符的最优表示方式 一个包含100 000个字符的文件 各字符出现频率不同
  • [ Note]python字符串的json 格式化美化输出

    通过爬虫获取到的json文件是字符串 vscode的prettify json失效 参考 json dumps参数之解 python的JSON用法 dumps的各种参数用法 详细 源码 jsonfile json dumps json文件
  • volatile的讲解以及宏定义和立即数

    volatile关键字 是用于表明变量代码无法被优化 比如 int a 0 a 1 a 2 a 3 经过编译器代码优化后 int a 0 a 3 省去重复工作 debug下不会作任何优化 但这样的代码效率一般只用在调试下 release模式
  • 2013小米笔试题--异形数

    题目 一个数组里 除了三个数是唯一出现的 其余的都出现偶数个 找出这三个数中的任一个 比如数组元素为 1 2 4 5 6 4 2 只有1 5 6这三个数字是唯一出现的 我们只需要输出1 5 6中的一个就行 分析 一般这样的题目采用异或的办法
  • nvm安装node ,yarn

    新电脑安装前端环境 1 先安装nvm 它是一个nodejs的版本管理工具 nvm 下载地址是github中的 推荐下载安装版 一键安装 自动配置环境变量 https github com coreybutler nvm windows re
  • HTTP协议系列教材 (二)- 借助FireFox火狐调试工具学习HTTP协议 

    对于HTTP协议的学习 我们将借助火狐浏览器FIREFOX的调试工具来实际观察浏览器和服务器之间传输数据的具体内容 步骤1 下载 FireFox步骤2 打开调试工具步骤3 观察 request response 步骤 1 下载 FireFo
  • 解决Jmeter返回数据中文乱码问题

    步骤1 修改jmeter中的配置文件jmeter properties的配置项sampleresult default encoding 修改为utf 8 解除注释后重启Jmeter 步骤2 添加后置处理器 BeanShell PostPr
  • 跟我学Java设计模式第三天:代理模式、适配器、装饰者等其中模式结构

    5 结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构 它分为类结构型模式和对象结构型模式 前者采用继承机制来组织接口和类 后者釆用组合或聚合来组合对象 由于组合关系或聚合关系比继承关系耦合度低 满足 合成复用原则 所以对象结
  • Java实现自定义注解

    前言 1 Java实现自定义注解其实很简单 跟类定义差不多 只是属性的定义可能跟我们平时定义的属性略有不同 这里会给大家详解 先来看代码 Target ElementType FIELD Retention RetentionPolicy
  • C++使用string的大数运算(4)除法

    本次项目目标 使用C 完成对于大数的相关运算 项目要点 1 大数指的是远超long long int的数据 2 将大数用矩阵进行存储 并通过矩阵实现运算 3 本人采用字符串进行存储 应注意char的特点 比如 char a 161 cout
  • OpenErp的权限

    首先引用一篇入门文章 http www oscg cn openerp develop doc 09 可以发现 其实openerp的权限分成了多层次的 菜单 视图 对象 规则 从字面意思就是每层都控制着自己对应的权限 然后我创建了一个新的g
  • HTML5 canvas 计算文字宽度的方法(measureText)

    var c document getElementById myCanvas var ctx c getContext 2d ctx font 30px Arial var txt Hello World ctx fillText widt
  • IEEE 802.3ad 链路聚合与LACP的简单知识&EtherChannel 总结

    IEEE 802 3ad 链路聚合与LACP的简单知识 内容提要 本文主要介绍了链路聚合的概念以及链路聚合与EtherChannel 以太通道 的区别 说明 IEEE 802 3ad 是执行链路聚合的标准方法 从概念上讲 将多个以太网适配器
  • 国内首个行业级燃机智慧运维云平台是如何炼成的?

    在未来的能源结构转型中 燃气发电将发挥重要作用 这似乎颠覆了人们日常认知 众所周知 在碳达峰 碳中和的环保目标下 我国能源结构正迎来根本性变革 传统化石能源占比将逐步下降 绿色低碳的新能源占比将持续提升 为何还要推动燃气发电的发展 这绝非虚
  • android edittext setonkeylistener,Android EditText 键入事件 —setOnKeyListener

    main xml android orientation vertical android layout width fill parent android layout height fill parent gt android layo
  • Vue简单示例——weex

    weex的生命周期 因为我们的Weex和Vue是绑定在一起的 所以我们讨论关于生命周期时 说的实际上是在Weex中可以使用的Vuex的生命周期 也就是Weex对于Vue生命周期的支持 好消息 Weex支持大部分的Vue中的生命周期钩子函数
  • apple mobile device服务无法启动,错误1053 解决

    本文转载自 https www cnblogs com relax p 3476741 html 作者 relax 转载请注明该声明 我不想安装iTunes 于是下了iTunes64安装包 解压后得到6个文件 安装完 AppleMobile
  • 进程的描述与控制(二)_OS

    目录 1 进程与线程的比较 2 线程的实现方式 内核支持线程 KST 用户级线程 ULT ULT KST 组合方式 3 进程同步的概念 4 两种形式的制约关系 5 临界资源 6 对临界资源访问的过程 7 同步机制应该遵循的规则 8 解决临界
  • 轻松应对IDC机房带宽突然暴涨问题

    轻松应对IDC机房带宽突然暴涨问题 1 提出问题 实际案例一 凌晨3 00点某公司 网站业务 的一个IDC机房带宽流量突然从平时高峰期150M猛增至1000M 如下图 该故障的影响 直接导致数百台服务器无法连接 该机房全部业务中断 实际案例
  • [深度学习实战]基于PyTorch的深度学习实战(下)

    目录 一 前言 二 Mnist手写数字图像识别 2 1 加载数据 2 1 1 下载地址 2 1 2 用 numpy 读取 mnist npz 2 2 定义卷积模型 2 3 开始训练 2 4 完整代码 2 5 验证结果 2 6 修改参数 三