first commit

This commit is contained in:
Jingfan Ke 2023-10-10 09:42:31 +08:00
commit 175bf7b7da
12 changed files with 3102 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
dataset/

File diff suppressed because it is too large Load Diff

6
Lab1/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
},
"python.formatting.provider": "none"
}

File diff suppressed because it is too large Load Diff

39
Lab1/code/1.1.py Normal file
View File

@ -0,0 +1,39 @@
import torch
A = torch.tensor([[1, 2, 3]])
B = torch.tensor([[4],
[5]])
# 方法1: 使用PyTorch的减法操作符
result1 = A - B
# 方法2: 使用PyTorch的sub函数
result2 = torch.sub(A, B)
# 方法3: 手动实现广播机制并作差
def mysub(a:torch.Tensor, b:torch.Tensor):
if not (
(a.size(0) == 1 and b.size(1) == 1)
or
(a.size(1) == 1 and b.size(0) == 1)
):
raise ValueError("输入的张量大小无法满足广播机制的条件。")
else:
target_shape = torch.Size([max(A.size(0), B.size(0)), max(A.size(1), B.size(1))])
A_broadcasted = A.expand(target_shape)
B_broadcasted = B.expand(target_shape)
result = torch.zeros(target_shape, dtype=torch.int64).to(device=A_broadcasted.device)
for i in range(target_shape[0]):
for j in range(target_shape[1]):
result[i, j] = A_broadcasted[i, j] - B_broadcasted[i, j]
return result
result3 = mysub(A, B)
print("方法1的结果:")
print(result1)
print("方法2的结果:")
print(result2)
print("方法3的结果:")
print(result3)

23
Lab1/code/1.2.py Normal file
View File

@ -0,0 +1,23 @@
import torch
mean = 0
stddev = 0.01
P = torch.normal(mean=mean, std=stddev, size=(3, 2))
Q = torch.normal(mean=mean, std=stddev, size=(4, 2))
print("矩阵 P:")
print(P)
print("矩阵 Q:")
print(Q)
# 对矩阵Q进行转置操作得到矩阵Q的转置Q^T
QT = Q.T
print("矩阵 QT:")
print(QT)
# 计算矩阵P和矩阵Q^T的矩阵相乘
result = torch.matmul(P, QT)
print("矩阵相乘的结果:")
print(result)

12
Lab1/code/1.3.py Normal file
View File

@ -0,0 +1,12 @@
import torch
x = torch.tensor(1.0, requires_grad=True)
y_1 = x**2
with torch.no_grad():
y_2 = x**3
y3 = y_1 + y_2
y3.backward()
print("梯度(dy_3/dx): ", x.grad.item())

143
Lab1/code/2.1.py Normal file
View File

@ -0,0 +1,143 @@
import numpy as np
import torch
from torch.autograd import Variable
from torch.utils.data import Dataset, DataLoader
from tqdm import tqdm
import ipdb
class My_BCELoss:
def __call__(self, prediction: torch.Tensor, target: torch.Tensor):
loss = -torch.mean(
target * torch.log(prediction) + (1 - target) * torch.log(1 - prediction)
)
return loss
class My_optimizer:
def __init__(self, params: list[torch.Tensor], lr: float):
self.params = params
self.lr = lr
def step(self):
for param in self.params:
param.data = param.data - self.lr * param.grad.data
def zero_grad(self):
for param in self.params:
if param.grad is not None:
param.grad.data.zero_()
class My_Linear:
def __init__(self, input_feature: int, output_feature: int):
self.weight = torch.randn(
(output_feature, input_feature), requires_grad=True, dtype=torch.float32
)
self.bias = torch.randn(1, requires_grad=True, dtype=torch.float32)
self.params = [self.weight, self.bias]
def __call__(self, x):
return self.forward(x)
def forward(self, x):
x = torch.matmul(x, self.weight.T) + self.bias
return x
def to(self, device: str):
for param in self.params:
param.data = param.data.to(device=device)
return self
def parameters(self):
return self.params
class Model:
def __init__(self):
self.linear = My_Linear(1, 1)
self.params = self.linear.params
def __call__(self, x):
return self.forward(x)
def forward(self, x):
x = self.linear(x)
x = torch.sigmoid(x)
return x
def to(self, device: str):
for param in self.params:
param.data = param.data.to(device=device)
return self
def parameters(self):
return self.params
class My_Dataset(Dataset):
def __init__(self, data_size=1000000):
np.random.seed(0)
x = 2 * np.random.rand(data_size, 1)
noise = 0.2 * np.random.randn(data_size, 1)
y = 4 - 3 * x + noise
self.min_x, self.max_x = np.min(x), np.max(x)
min_y, max_y = np.min(y), np.max(y)
x = (x - self.min_x) / (self.max_x - self.min_x)
y = (y - min_y) / (max_y - min_y)
self.data = [[x[i][0], y[i][0]] for i in range(x.shape[0])]
def __len__(self):
return len(self.data)
def __getitem__(self, index):
x, y = self.data[index]
return x, y
learning_rate = 5e-2
num_epochs = 10
batch_size = 1024
device = "cuda:0" if torch.cuda.is_available() else "cpu"
dataset = My_Dataset()
dataloader = DataLoader(
dataset=dataset, batch_size=batch_size, shuffle=True, num_workers=5, pin_memory=True
)
model = Model().to(device)
criterion = My_BCELoss()
optimizer = My_optimizer(model.parameters(), lr=learning_rate)
for epoch in range(num_epochs):
total_epoch_loss = 0
total_epoch_pred = 0
total_epoch_target = 0
for index, (x, targets) in tqdm(enumerate(dataloader), total=len(dataloader)):
optimizer.zero_grad()
x = x.to(device).to(dtype=torch.float32)
targets = targets.to(device).to(dtype=torch.float32)
x = x.unsqueeze(1)
y_pred = model(x)
loss = criterion(y_pred, targets)
total_epoch_loss += loss.item()
total_epoch_target += targets.sum().item()
total_epoch_pred += y_pred.sum().item()
loss.backward()
optimizer.step()
print(
f"Epoch {epoch + 1}/{num_epochs}, Loss: {total_epoch_loss}, Acc: {1 - abs(total_epoch_pred - total_epoch_target) / total_epoch_target}"
)
with torch.no_grad():
test_data = (np.array([[2]]) - dataset.min_x) / (dataset.max_x - dataset.min_x)
test_data = Variable(
torch.tensor(test_data, dtype=torch.float64), requires_grad=False
).to(device)
predicted = model(test_data).to("cpu")
print(
f"Model weights: {model.linear.weight.item()}, bias: {model.linear.bias.item()}"
)
print(f"Prediction for test data: {predicted.item()}")

89
Lab1/code/2.2.py Normal file
View File

@ -0,0 +1,89 @@
import numpy as np
import torch
from torch.autograd import Variable
from torch.utils.data import Dataset, DataLoader
from torch import nn
from tqdm import tqdm
import ipdb
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.linear = nn.Linear(1, 1, dtype=torch.float64)
def forward(self, x):
x = self.linear(x)
x = torch.sigmoid(x)
return x
class My_Dataset(Dataset):
def __init__(self, data_size=1000000):
np.random.seed(0)
x = 2 * np.random.rand(data_size, 1)
noise = 0.2 * np.random.randn(data_size, 1)
y = 4 - 3 * x + noise
self.min_x, self.max_x = np.min(x), np.max(x)
min_y, max_y = np.min(y), np.max(y)
x = (x - self.min_x) / (self.max_x - self.min_x)
y = (y - min_y) / (max_y - min_y)
self.data = [[x[i][0], y[i][0]] for i in range(x.shape[0])]
def __len__(self):
return len(self.data)
def __getitem__(self, index):
x, y = self.data[index]
return x, y
learning_rate = 1e-2
num_epochs = 10
batch_size = 1024
device = "cuda:0" if torch.cuda.is_available() else "cpu"
dataset = My_Dataset()
dataloader = DataLoader(
dataset=dataset, batch_size=batch_size, shuffle=True, num_workers=5, pin_memory=True
)
model = Model().to(device)
criterion = nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for epoch in range(num_epochs):
total_epoch_loss = 0
total_epoch_pred = 0
total_epoch_target = 0
for index, (x, targets) in tqdm(enumerate(dataloader), total=len(dataloader)):
optimizer.zero_grad()
x = x.to(device)
targets = targets.to(device)
x = x.unsqueeze(1)
targets = targets.unsqueeze(1)
y_pred = model(x)
loss = criterion(y_pred, targets)
total_epoch_loss += loss.item()
total_epoch_target += targets.sum().item()
total_epoch_pred += y_pred.sum().item()
loss.backward()
optimizer.step()
print(
f"Epoch {epoch + 1}/{num_epochs}, Loss: {total_epoch_loss}, Acc: {1 - abs(total_epoch_pred - total_epoch_target) / total_epoch_target}"
)
with torch.no_grad():
test_data = (np.array([[2]]) - dataset.min_x) / (dataset.max_x - dataset.min_x)
test_data = Variable(
torch.tensor(test_data, dtype=torch.float64), requires_grad=False
).to(device)
predicted = model(test_data).to("cpu")
print(
f"Model weights: {model.linear.weight.item()}, bias: {model.linear.bias.item()}"
)
print(f"Prediction for test data: {predicted.item()}")

169
Lab1/code/3.1.py Normal file
View File

@ -0,0 +1,169 @@
import numpy as np
import torch
from torch.utils.data import Dataset, DataLoader
from torch import nn
from tqdm import tqdm
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
def my_one_hot(indices: torch.Tensor, num_classes: int):
one_hot_tensor = torch.zeros(len(indices), num_classes).to(indices.device)
one_hot_tensor.scatter_(1, indices.view(-1, 1), 1)
return one_hot_tensor
class My_CrossEntropyLoss:
def __call__(self, predictions: torch.Tensor, targets: torch.Tensor):
max_values = torch.max(predictions, dim=1, keepdim=True).values
exp_values = torch.exp(predictions - max_values)
softmax_output = exp_values / torch.sum(exp_values, dim=1, keepdim=True)
log_probs = torch.log(softmax_output)
nll_loss = -torch.sum(targets * log_probs, dim=1)
average_loss = torch.mean(nll_loss)
return average_loss
class My_optimizer:
def __init__(self, params: list[torch.Tensor], lr: float):
self.params = params
self.lr = lr
def step(self):
for param in self.params:
param.data = param.data - self.lr * param.grad.data
def zero_grad(self):
for param in self.params:
if param.grad is not None:
param.grad.data.zero_()
class My_Linear:
def __init__(self, input_feature: int, output_feature: int):
self.weight = torch.randn(
(output_feature, input_feature), requires_grad=True, dtype=torch.float32
)
self.bias = torch.randn(1, requires_grad=True, dtype=torch.float32)
self.params = [self.weight, self.bias]
def __call__(self, x: torch.Tensor):
return self.forward(x)
def forward(self, x: torch.Tensor):
x = torch.matmul(x, self.weight.T) + self.bias
return x
def to(self, device: str):
for param in self.params:
param.data = param.data.to(device=device)
return self
def parameters(self):
return self.params
class My_Flatten:
def __call__(self, x: torch.Tensor):
return self.forward(x)
def forward(self, x: torch.Tensor):
x = x.view(x.shape[0], -1)
return x
class Model_3_1:
def __init__(self, num_classes):
self.flatten = My_Flatten()
self.linear = My_Linear(28 * 28, num_classes)
self.params = self.linear.params
def __call__(self, x: torch.Tensor):
return self.forward(x)
def forward(self, x: torch.Tensor):
x = self.flatten(x)
x = self.linear(x)
return x
def to(self, device: str):
for param in self.params:
param.data = param.data.to(device=device)
return self
def parameters(self):
return self.params
learning_rate = 5e-3
num_epochs = 10
batch_size = 4096
num_classes = 10
device = "cuda:0" if torch.cuda.is_available() else "cpu"
transform = transforms.Compose(
[
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)),
]
)
train_dataset = datasets.FashionMNIST(
root="./dataset", train=True, transform=transform, download=True
)
test_dataset = datasets.FashionMNIST(
root="./dataset", train=False, transform=transform, download=True
)
train_loader = DataLoader(
dataset=train_dataset,
batch_size=batch_size,
shuffle=True,
num_workers=4,
pin_memory=True,
)
test_loader = DataLoader(
dataset=test_dataset,
batch_size=batch_size,
shuffle=True,
num_workers=4,
pin_memory=True,
)
model = Model_3_1(num_classes).to(device)
criterion = My_CrossEntropyLoss()
optimizer = My_optimizer(model.parameters(), lr=learning_rate)
for epoch in range(num_epochs):
total_epoch_loss = 0
for index, (images, targets) in tqdm(
enumerate(train_loader), total=len(train_loader)
):
optimizer.zero_grad()
images = images.to(device)
targets = targets.to(device).to(dtype=torch.long)
one_hot_targets = (
my_one_hot(targets, num_classes=num_classes).to(device).to(dtype=torch.long)
)
outputs = model(images)
# ipdb.set_trace()
loss = criterion(outputs, one_hot_targets)
total_epoch_loss += loss
loss.backward()
optimizer.step()
total_acc = 0
with torch.no_grad():
for index, (image, targets) in tqdm(
enumerate(test_loader), total=len(test_loader)
):
image = image.to(device)
targets = targets.to(device)
outputs = model(image)
total_acc += (outputs.argmax(1) == targets).sum()
print(
f"Epoch {epoch + 1}/{num_epochs} Train, Loss: {total_epoch_loss}, Acc: {total_acc / len(test_dataset)}"
)

96
Lab1/code/3.2.py Normal file
View File

@ -0,0 +1,96 @@
import numpy as np
import torch
from torch.utils.data import DataLoader
from torch import nn
from tqdm import tqdm
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import ipdb
class Model(nn.Module):
def __init__(self, num_classes):
super(Model, self).__init__()
self.flatten = nn.Flatten()
self.linear = nn.Linear(28 * 28, num_classes)
def forward(self, x: torch.Tensor):
x = self.flatten(x)
x = self.linear(x)
return x
learning_rate = 5e-3
num_epochs = 10
batch_size = 4096
num_classes = 10
device = "cuda:0" if torch.cuda.is_available() else "cpu"
transform = transforms.Compose(
[
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)),
]
)
train_dataset = datasets.FashionMNIST(
root="./dataset", train=True, transform=transform, download=True
)
test_dataset = datasets.FashionMNIST(
root="./dataset", train=False, transform=transform, download=True
)
train_loader = DataLoader(
dataset=train_dataset,
batch_size=batch_size,
shuffle=True,
num_workers=4,
pin_memory=True,
)
test_loader = DataLoader(
dataset=test_dataset,
batch_size=batch_size,
shuffle=True,
num_workers=4,
pin_memory=True,
)
model = Model(num_classes).to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for epoch in range(num_epochs):
total_epoch_loss = 0
model.train()
for index, (images, targets) in tqdm(
enumerate(train_loader), total=len(train_loader)
):
optimizer.zero_grad()
images = images.to(device)
targets = targets.to(device)
one_hot_targets = (
torch.nn.functional.one_hot(targets, num_classes=num_classes)
.to(device)
.to(dtype=torch.float32)
)
outputs = model(images)
loss = criterion(outputs, one_hot_targets)
total_epoch_loss += loss
loss.backward()
optimizer.step()
model.eval()
total_acc = 0
with torch.no_grad():
for index, (image, targets) in tqdm(
enumerate(test_loader), total=len(test_loader)
):
image = image.to(device)
targets = targets.to(device)
outputs = model(image)
total_acc += (outputs.argmax(1) == targets).sum()
print(
f"Epoch {epoch + 1}/{num_epochs} Train, Loss: {total_epoch_loss}, Acc: {total_acc / len(test_dataset)}"
)

BIN
images/school_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB