深度学习pytorch常用操作以及流程
在微信公众号上看到这篇文章,担心以后想找的时候迷路,所以记录到了自己的博客上,侵扰致歉,随时联系可删除。
1.基本张量操作
1. 1 创建张量
介绍: torch.tensor()
是 PyTorch 中用于创建张量的基本函数。
简单使用:
import torch
# 创建一个标量(零维张量)
scalar_tensor = torch.tensor(42)
print(scalar_tensor)
# 创建一个一维张量
vector_tensor = torch.tensor([1, 2, 3])
print(vector_tensor)
# 创建一个二维张量
matrix_tensor = torch.tensor([[1, 2], [3, 4]])
print(matrix_tensor)
1.2 张量形状变换
介绍: torch.view()
用于改变张量的形状,但要确保元素数量不变。
简单使用:
import torch
# 创建一个一维张量
original_tensor = torch.arange(1, 9) # 1, 2, 3, ..., 8
print("原始张量:", original_tensor)
# 将一维张量转换为二维张量
reshaped_tensor = original_tensor.view(2, 4)
print("形状变换后的张量:", reshaped_tensor)
1.3 张量拼接
介绍: torch.cat()
用于沿指定维度拼接张量。
简单使用:
import torch
# 创建两个张量
tensor1 = torch.tensor([[1, 2], [3, 4]])
tensor2 = torch.tensor([[5, 6]])
# 沿着行维度拼接张量
concatenated_tensor = torch.cat((tensor1, tensor2), dim=0)
print("拼接后的张量:", concatenated_tensor)
1.4 张量索引与切片
介绍: 使用索引和切片可以获取张量的特定元素或子集。
简单使用:
import torch
# 创建一个二维张量
matrix_tensor = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 获取第一行
first_row = matrix_tensor[0, :]
print("第一行:", first_row)
# 获取第一列
first_column = matrix_tensor[:, 0]
print("第一列:", first_column)
# 切片获取子集
subset_tensor = matrix_tensor[1:, 1:]
print("子集张量:", subset_tensor)
2.重要的张量处理方式
2.1 张量转置
介绍: torch.t()
用于计算矩阵的转置。
简单使用:
import torch
# 创建一个二维张量
matrix_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
# 计算转置
transposed_tensor = torch.t(matrix_tensor)
print("转置后的张量:", transposed_tensor)
2.2 矩阵乘法
介绍: torch.mm()
用于计算两个矩阵的乘积。
简单使用:
import torch
# 创建两个矩阵
matrix1 = torch.tensor([[1, 2], [3, 4]])
matrix2 = torch.tensor([[5, 6], [7, 8]])
# 计算矩阵乘积
result_matrix = torch.mm(matrix1, matrix2)
print("矩阵乘积:", result_matrix)
2.3 元素级乘法
介绍: torch.mul()
用于执行两个张量的元素级乘法。
简单使用:
import torch
# 创建两个张量
tensor1 = torch.tensor([[1, 2], [3, 4]])
tensor2 = torch.tensor([[5, 6], [7, 8]])
# 元素级乘法
result_tensor = torch.mul(tensor1, tensor2)
print("元素级乘法结果:", result_tensor)
2.4 求和
介绍: torch.sum()
用于计算张量元素的和。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1, 2], [3, 4]])
# 计算张量元素的和
sum_result = torch.sum(tensor)
print("张量元素的和:", sum_result)
2.5 平均值
介绍: torch.mean()
用于计算张量元素的平均值。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
# 计算张量元素的平均值
mean_result = torch.mean(tensor)
print("张量元素的平均值:", mean_result)
3.张量:数学和统计功能
3.1 标准差
介绍: torch.std()
用于计算张量元素的标准差。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
# 计算张量元素的标准差
std_result = torch.std(tensor)
print("张量元素的标准差:", std_result)
3.2 最大值
介绍: torch.max()
用于找到张量中的最大值及其索引。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1, 2], [3, 4]])
# 找到张量中的最大值及其索引
max_value, max_index = torch.max(tensor, dim=1)
print("最大值:", max_value)
print("最大值索引:", max_index)
3.3 最小值
介绍: torch.min()
用于找到张量中的最小值及其索引。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1, 2], [3, 4]])
# 找到张量中的最小值及其索引
min_value, min_index = torch.min(tensor, dim=1)
print("最小值:", min_value)
print("最小值索引:", min_index)
3.4 绝对值
介绍: torch.abs()
用于计算张量元素的绝对值。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[-1, 2], [-3, 4]])
# 计算张量元素的绝对值
abs_result = torch.abs(tensor)
print("张量元素的绝对值:", abs_result)
3.5 指数运算
介绍: torch.exp()
用于计算张量元素的指数。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
# 计算张量元素的指数
exp_result = torch.exp(tensor)
print("张量元素的指数:", exp_result)
3.6 对数运算
介绍: torch.log()
用于计算张量元素的自然对数。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
# 计算张量元素的自然对数
log_result = torch.log(tensor)
print("张量元素的自然对数:", log_result)
4.张量:深度学习方面的操作
4.1 向下取整
介绍: torch.floor()
用于将张量元素向下取整,得到不超过每个元素的最大整数。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1.2, 2.8], [3.5, 4.1]])
# 向下取整
floor_result = torch.floor(tensor)
print("向下取整结果:", floor_result)
4.2 向上取整
介绍: torch.ceil()
用于将张量元素向上取整,得到不小于每个元素的最小整数。
简单使用:
import torch
# 创建一个张量
tensor = torch.tensor([[1.2, 2.8], [3.5, 4.1]])
# 向上取整
ceil_result = torch.ceil(tensor)
print("向上取整结果:", ceil_result)
4.3 梯度清零
介绍: 在训练深度学习模型时,使用 optimizer.zero_grad()
将梯度清零是一个常见的步骤,以防止梯度累积。
简单使用:
import torch
import torch.optim as optim
# 创建一个模型和优化器
model = torch.nn.Linear(3, 1)
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 前向传播、反向传播、梯度清零
input_data = torch.randn(10, 3)
output = model(input_data)
loss = torch.nn.functional.mse_loss(output, torch.randn(10, 1))
loss.backward()
optimizer.zero_grad()
4.4 梯度裁剪
介绍: 用于防止梯度爆炸的技术,通过对模型的梯度进行裁剪。
简单使用:
import torch
import torch.nn as nn
import torch.optim as optim
# 创建一个模型和优化器
model = nn.Linear(3, 1)
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 前向传播、反向传播
input_data = torch.randn(10, 3)
output = model(input_data)
loss = torch.nn.functional.mse_loss(output, torch.randn(10, 1))
loss.backward()
# 梯度裁剪
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
4.5 数据加载与处理
介绍: torch.utils.data
模块提供了用于加载和处理数据的工具,包括 DataLoader
和 Dataset
等类。
简单使用:
import torch
from torch.utils.data import DataLoader, Dataset
# 自定义数据集类
class CustomDataset(Dataset):
def __init__(self, data):
self.data = data
def __len__(self):
return len(self.data)
def __getitem__(self, index):
return self.data[index]
# 创建自定义数据集实例
my_dataset = CustomDataset([1, 2, 3, 4, 5])
# 创建数据加载器
data_loader = DataLoader(my_dataset, batch_size=2, shuffle=True)
# 迭代数据加载器
for batch in data_loader:
print("Batch:", batch)
5.训练和优化的核心概念
5.1 模型定义与搭建
介绍: torch.nn.Module
是 PyTorch 中用于定义和搭建模型的基类。通过继承该类,可以创建自定义的深度学习模型。
简单使用:
import torch
import torch.nn as nn
# 自定义模型类
class SimpleModel(nn.Module):
def __init__(self, input_size, output_size):
super(SimpleModel, self).__init__()
self.linear = nn.Linear(input_size, output_size)
def forward(self, x):
return self.linear(x)
# 创建模型实例
model = SimpleModel(input_size=10, output_size=5)
# 查看模型结构
print(model)
5.2 损失函数
介绍: torch.nn.functional
模块提供了多种损失函数,例如均方误差损失(mse_loss
)、交叉熵损失(cross_entropy
)等。
简单使用:
import torch
import torch.nn.functional as F
# 创建模型输出和目标标签
output = torch.randn(3, 5)
target = torch.randint(5, (3,), dtype=torch.long)
# 计算交叉熵损失
loss = F.cross_entropy(output, target)
print("交叉熵损失:", loss.item())
5.3 优化器
介绍: torch.optim
模块提供了多种优化器,例如随机梯度下降(SGD
)、Adam 等。
简单使用:
import torch
import torch.optim as optim
# 创建模型和优化器
model = SimpleModel(input_size=10, output_size=5)
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 在训练循环中使用优化器
for epoch in range(10):
# ... 其他训练步骤 ...
# 梯度清零
optimizer.zero_grad()
# 计算损失
loss = compute_loss()
# 反向传播
loss.backward()
# 参数更新
optimizer.step()
5.4 学习率调度
介绍: torch.optim.lr_scheduler
模块提供了多种学习率调度器,例如学习率衰减等。
简单使用:
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
# 创建模型、优化器和学习率调度器
model = SimpleModel(input_size=10, output_size=5)
optimizer = optim.SGD(model.parameters(), lr=0.01)
scheduler = StepLR(optimizer, step_size=5, gamma=0.1)
# 在训练循环中使用学习率调度器
for epoch in range(20):
# ... 其他训练步骤 ...
# 梯度清零
optimizer.zero_grad()
# 计算损失
loss = compute_loss()
# 反向传播
loss.backward()
# 参数更新
optimizer.step()
# 更新学习率
scheduler.step()
5.5 模型保存与加载
介绍: torch.save()
和 torch.load()
用于模型的保存和加载。
简单使用:
import torch
# 保存模型
torch.save(model.state_dict(), 'model.pth')
# 加载模型
loaded_model = SimpleModel(input_size=10, output_size=5)
loaded_model.load_state_dict(torch.load('model.pth'))
5.6 GPU 加速
介绍: PyTorch 允许在GPU上运行张量和模型,以加速深度学习任务。
简单使用:
import torch
# 检查是否有可用的GPU
if torch.cuda.is_available():
# 将模型和张量移动到GPU
model = model.cuda()
tensor = tensor.cuda()
5.7 分布式训练
介绍: PyTorch 支持分布式训练,使得可以在多个GPU或多台机器上进行模型训练。
简单使用:
import torch
import torch.nn as nn
import torch.optim as optim
import torch.multiprocessing as mp
import torch.distributed as dist
# 初始化分布式训练环境
mp.spawn(train, nprocs=4, args=(model, criterion, optimizer, train_loader))
5.8 数据并行与模型并行
介绍: 数据并行是将数据分布在多个GPU上进行处理,而模型并行是将模型的不同部分分布在多个GPU上。
简单使用:
import torch
import torch.nn as nn
# 数据并行
model = nn.DataParallel(model)
# 模型并行
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
self.part1 = nn.Linear(10, 5)
self.part2 = nn.Linear(5, 1)
# 将模型的不同部分放在不同的GPU上
model_part1 = MyModel().part1.cuda(0)
model_part2 = MyModel().part2.cuda(1)
6.pytorch 高级框架和工具
6.1 图像处理与加载
介绍: torchvision.transforms
模块提供了许多用于图像处理和加载的转换操作,例如裁剪、旋转、缩放等。
简单使用:
import torch
from torchvision import transforms
from PIL import Image
# 定义图像转换
transform = transforms.Compose([
transforms.Resize((256, 256)),
transforms.RandomCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
])
# 加载图像并应用转换
image = Image.open('example.jpg')
transformed_image = transform(image)
6.2 图像加载
介绍: torchvision.datasets.ImageFolder
允许从文件夹中加载图像数据集。
简单使用:
import torch
from torchvision import datasets, transforms
# 定义图像转换
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
])
# 加载图像数据集
dataset = datasets.ImageFolder(root='path/to/data', transform=transform)
7.自定义操作
7.1 自定义损失函数
介绍: 你可以通过继承 torch.nn.Module
类来创建自定义的损失函数。
简单使用:
import torch
import torch.nn as nn
# 自定义损失函数类
class CustomLoss(nn.Module):
def __init__(self, weight):
super(CustomLoss, self).__init__()
self.weight = weight
def forward(self, predictions, targets):
loss = torch.mean((predictions - targets) ** 2)
weighted_loss = self.weight * loss
return weighted_loss
# 使用自定义损失函数
loss_function = CustomLoss(weight=0.5)
7.2 自定义初始化方法
介绍: 你可以自定义模型参数的初始化方法。
简单使用:
import torch.nn.init as init
# 自定义初始化方法
def custom_init(m):
if isinstance(m, nn.Linear):
init.constant_(m.weight, val=0.1)
init.constant_(m.bias, val=0)
# 在模型中应用初始化方法
model.apply(custom_init)
7.3 自定义学习率调度器
介绍: 你可以通过继承 torch.optim.lr_scheduler._LRScheduler
类来创建自定义学习率调度器。
简单使用:
import torch.optim as optim
# 自定义学习率调度器类
class CustomLRScheduler(optim.lr_scheduler._LRScheduler):
def __init__(self, optimizer):
super(CustomLRScheduler, self).__init__(optimizer)
def get_lr(self):
# 自定义学习率调度逻辑
pass
# 使用自定义学习率调度器
optimizer = optim.SGD(model.parameters(), lr=0.01)
lr_scheduler = CustomLRScheduler(optimizer)
7.4 可视化工具
介绍: 使用可视化工具可以更好地理解模型的训练过程。
简单使用:
from torch.utils.tensorboard import SummaryWriter
# 创建 TensorBoard 写入器
writer = SummaryWriter()
# 写入标量值
writer.add_scalar('Loss', loss, global_step=epoch)
# 写入模型结构
writer.add_graph(model, input_data)
# 在命令行中运行 TensorBoard
# tensorboard --logdir=runs
7.5 自定义数据加载器
介绍: 继承 torch.utils.data.Dataset
类可以自定义数据加载器。
简单使用:
from torch.utils.data import Dataset
# 自定义数据加载器类
class CustomDataset(Dataset):
def __init__(self, data, labels):
self.data = data
self.labels = labels
def __len__(self):
return len(self.data)
def __getitem__(self, index):
return self.data[index], self.labels[index]
# 使用自定义数据加载器
custom_dataset = CustomDataset(data, labels)
7.6 PyTorch 转 ONNX
介绍: 将 PyTorch 模型转换为 ONNX(Open Neural Network Exchange)格式,以在其他框架或硬件上部署模型。
简单使用:
import torch
import torchvision.models as models
# 加载预训练模型
model = models.resnet18(pretrained=True)
# 将 PyTorch 模型转为 ONNX 格式
dummy_input = torch.randn(1, 3, 224, 224)
onnx_path = "resnet18.onnx"
torch.onnx.export(model, dummy_input, onnx_path, verbose=True)
7.7 混合精度训练
介绍: 使用混合精度训练可以加速模型训练,减少显存占用。
简单使用:
import torch
from torch.cuda.amp import autocast, GradScaler
# 创建模型和优化器
model = ...
optimizer = ...
# 创建混合精度训练的梯度缩放器
scaler = GradScaler()
# 在训练循环中使用混合精度训练
for epoch in range(num_epochs):
for input_data, target in train_loader:
optimizer.zero_grad()
# 使用 autocast 将前向传播、损失计算和反向传播放在混合精度环境中
with autocast():
output = model(input_data)
loss = loss_fn(output, target)
# 反向传播和梯度更新
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
7.8 PyTorch 中的异步数据加载
介绍: PyTorch 允许使用 torch.utils.data.DataLoader
的 num_workers
参数实现异步数据加载,加速数据加载过程。
简单使用:
import torch
from torch.utils.data import DataLoader
# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4)
7.9 PyTorch 中的分布式训练与模型并行
介绍: PyTorch 支持分布式训练,可以在多个 GPU 或多台机器上进行模型训练。此外,PyTorch 也支持模型并行,允许将模型的不同部分分布在多个 GPU 上。
简单使用:
import torch
import torch.nn as nn
import torch.optim as optim
import torch.distributed as dist
from torch.nn.parallel import DistributedDataParallel
# 初始化分布式训练环境
dist.init_process_group(backend='nccl', init_method='tcp://localhost:23456', rank=0, world_size=1)
# 创建模型并将其移到 GPU
model = nn.Sequential(nn.Linear(10, 5), nn.ReLU(), nn.Linear(5, 1))
model = model.to('cuda')
# 使用 DistributedDataParallel 包装模型
model = DistributedDataParallel(model)
# 定义优化器和损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01)
criterion = nn.MSELoss()
# 在训练循环中使用 DistributedDataParallel
for epoch in range(num_epochs):
for input_data, target in train_loader:
input_data, target = input_data.to('cuda'), target.to('cuda')
output = model(input_data)
loss = criterion(output, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 在命令行中使用多 GPU 训练:
# python -m torch.distributed.launch --nproc_per_node=NUM_GPUS your_training_script.py
7.10 PyTorch 中的自动微分(Autograd)
介绍: PyTorch 中的 Autograd 模块提供了自动微分的功能,可以方便地计算梯度。
简单使用:
import torch
# 创建一个需要梯度的张量
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
# 定义一个计算图
y = x.pow(2).sum()
# 反向传播,计算梯度
y.backward()
# 获取梯度
print(x.grad)
7.11 PyTorch 中的动态计算图
介绍: PyTorch 中的计算图是动态的,允许根据实际执行情况动态构建计算图。
简单使用:
import torch
# 创建动态计算图
def dynamic_computation(x):
if x.sum() > 0:
return x * 2
else:
return x * 3
# 构建计算图
x = torch.tensor([1.0, -1.0], requires_grad=True)
result = dynamic_computation(x)
# 反向传播,计算梯度
result.sum().backward()
# 获取梯度
print(x.grad)
7.12 PyTorch 中的模型保存与加载
介绍: PyTorch 提供了保存和加载模型的工具,可以保存整个模型或仅保存模型的参数。
简单使用:
import torch
# 定义一个简单的模型
class SimpleModel(torch.nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc = torch.nn.Linear(10, 5)
def forward(self, x):
return self.fc(x)
# 创建模型实例
model = SimpleModel()
# 保存整个模型
torch.save(model, 'whole_model.pth')
# 保存模型参数
torch.save(model.state_dict(), 'model_params.pth')
# 加载整个模型
loaded_model = torch.load('whole_model.pth')
# 加载模型参数到新的模型实例
new_model = SimpleModel()
new_model.load_state_dict(torch.load('model_params.pth'))
import torch
import torch.nn as nn
# 创建模型和损失函数
model = ...
criterion = ...
# 创建数据加载器
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
# 模型评估
model.eval()
total_loss = 0.0
correct_predictions = 0
with torch.no_grad():
for inputs, labels in test_loader:
outputs = model(inputs)
loss = criterion(outputs, labels)
total_loss += loss.item()
_, predicted_class = torch.max(outputs, 1)
correct_predictions += (predicted_class == labels).sum().item()
average_loss = total_loss / len(test_loader.dataset)
accuracy = correct_predictions / len(test_loader.dataset)
print(f'Average Loss: {average_loss}, Accuracy: {accuracy}')
参考文章
【创作不易,望点赞收藏,若有疑问,请留言,谢谢】
深度学习pytorch常用操作以及流程的更多相关文章
- 深度学习之常用linux命令总结
深度学习中常用linux命令总结 1.创建文件夹 mkdir 文件名2.删除文件 rm -d 目录名 #删除一个空目录 rmdir 目录名 #删除一个空目录 rm -r 目录名 #删除一个非空目录 r ...
- [深度学习] Pytorch学习(一)—— torch tensor
[深度学习] Pytorch学习(一)-- torch tensor 学习笔记 . 记录 分享 . 学习的代码环境:python3.6 torch1.3 vscode+jupyter扩展 #%% im ...
- 深度学习--PyTorch定义Tensor以及索引和切片
深度学习--PyTorch定义Tensor 一.创建Tensor 1.1未初始化的方法 这些方法只是开辟了空间,所附的初始值(非常大,非常小,0),后面还需要我们进行数据的存入. torch.em ...
- [深度学习] Pytorch(三)—— 多/单GPU、CPU,训练保存、加载模型参数问题
[深度学习] Pytorch(三)-- 多/单GPU.CPU,训练保存.加载预测模型问题 上一篇实践学习中,遇到了在多/单个GPU.GPU与CPU的不同环境下训练保存.加载使用使用模型的问题,如果保存 ...
- 深度学习PyTorch环境安装——mac
参考:http://python.jobbole.com/87522/ 1.首先要安装Anaconda 1)什么是Anaconda Anaconda是Python的包管理器和环境管理器,是一个包含18 ...
- ubuntu的学习教程(常用操作)
摘要 最近在学习linux,把自己学习过程中遇到的常用操作以及一些有助于理解的内容记录下来.我主要用的是ubuntu系统 命令提示符 '~' 这个是指用户的家目录,用户分为root用户和普通用户,ro ...
- (数据科学学习手札141)利用Learn Git Branching轻松学习git常用操作
1 简介 大家好我是费老师,Git作为世界上最流行的版本控制系统,可以说是每一位与程序打交道的朋友最值得学习的软件之一.除了管理自己的项目,如果你对参与开源项目感兴趣,那么Git更是联结Github. ...
- 深度学习PyTorch入门(1):3060 Pytorch+pycharm环境搭建
WIN10, NVIDIA GeForce RTX 3060 python 3.7, CUDAv11.1.1, PyTorch 1.9, PyCharm 1.安装anacodah和PyCharm: ...
- [深度学习] pytorch学习笔记(2)(梯度、梯度下降、凸函数、鞍点、激活函数、Loss函数、交叉熵、Mnist分类实现、GPU)
一.梯度 导数是对某个自变量求导,得到一个标量. 偏微分是在多元函数中对某一个自变量求偏导(将其他自变量看成常数). 梯度指对所有自变量分别求偏导,然后组合成一个向量,所以梯度是向量,有方向和大小. ...
- [深度学习] pytorch学习笔记(1)(数据类型、基础使用、自动求导、矩阵操作、维度变换、广播、拼接拆分、基本运算、范数、argmax、矩阵比较、where、gather)
一.Pytorch安装 安装cuda和cudnn,例如cuda10,cudnn7.5 官网下载torch:https://pytorch.org/ 选择下载相应版本的torch 和torchvisio ...
随机推荐
- Chrome 插件 V3 版本 Manifest.json 中的内容脚本(Content Scripts)解析
内容脚本(Content Scripts) 指定在用户打开某些网页时要使用的 JavaScript 或 CSS 文件. 内容脚本是在网页环境中运行的文件.通过使用标准文档对象模型 (DOM),开发者能 ...
- CSS布局概念与技术教程
以下是一份CSS布局学习大纲,它涵盖了基本到高级的CSS布局概念和技术 引言 欢迎来到CSS教程!如果你已经掌握了HTML的基础知识,那么你即将进入一个全新的世界,通过学习CSS(Cascading ...
- smtplib详解,发送邮件
创建邮箱账号 1.官网登录邮箱. 2.在邮箱的主界面找到"设置",新版的主界面与旧版稍有不同,一般位于上方,齿轮状的即是. 3.点击齿轮状的设置标志,会弹出一个下拉菜单,在最后有我 ...
- webapi创建WCF WebService+WCF WebService远程服务调用
首先需要引入soapcore包 这个包提供了所需的类和soap终结点中间件. 引入这个这个包之后,我们需要定义提供的服务. 这里我写了一个用于查询省份面积的服务. 省份信息服务 /// <sum ...
- VisualStduio如何自定义代码片段
什么是代码片段 代码片段又叫CodeSnippet,可以用来快捷补全代码.其实我们经常使用这个功能. 比如for循环,输入for会弹出这个窗口 我们选择第二个for,再按两次Tab键,编辑器就会自动生 ...
- Swift Copy On Write 多线程下面的资源竞争
Swift中的String.Array.Dictionary等容器类型默认实现了写时复制,这个操作在多线程下面可能会带来错误 https://bugs.swift.org/browse/SR-6543
- 《剑指offer3- 从末尾到头打印链表》
题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 本质上是逆转链表 /** * struct ListNode { * int val; * struct ListN ...
- 8.11考试总结(NOIP模拟36)[Dove 打扑克·Cicada 与排序·Cicada 拿衣服]
我会化作人间的风雨陪在你的身边 T1 Dove 打扑克 解题思路 考场上是想了一个树状数组维护的打法,但是竟然和 \(qn^2\) 的算法一样是 65pts 暴力就是对于每一次 2 询问重新建一下树状 ...
- LeetCode 692. Top K Frequent Words 前K个高频单词 (Java)
题目: Given a non-empty list of words, return the k most frequent elements. Your answer should be sort ...
- Unity 3D 的NEW (堆内存)
用容器装 在AWEKE NEW 运行时NEW 会导致分配内存时界面卡住, new class 的时候 才刷新程序帧 AWEKE 是程序启动时还没走完第一帧的开头执行 AWEKE 里面的代码 常量也在A ...