import random
def get_rectangle():
width=random.random()
height=random.random()
# 如果width大于height就是1,否则就是0
fat=int(width>=height)
return width,height,fat
get_rectangle()
(0.19267437580138802, 0.645061020860627, 0)
fat=int(0.8>=0.9)
fat
0
import torch
class Dataset(torch.utils.data.Dataset):
def __init__(self):
pass
def __len__(self):
return 1000
def __getitem__(self,i):
width,height,fat=get_rectangle()
# 这里注意width和height列表形式再转为tensor,另外是floattensor
x=torch.FloatTensor([width,height])
y=fat
return x,y
dataset=Dataset()
# 这里没执行一次都要变,有什么意义?
len(dataset),dataset[999]
(1000, (tensor([0.4756, 0.1713]), 1))
# 定义了数据集,然后使用loader去加载,需要记住batch_size,shuffle,drop_last这个三个常用的
loader=torch.utils.data.DataLoader(dataset=dataset,batch_size=9,shuffle=True,drop_last=True)
# 加载完了以后,就可以使用next去遍历了
len(loader),next(iter(loader))
(111,
[tensor([[0.1897, 0.6766],
[0.2460, 0.2725],
[0.5871, 0.7739],
[0.3035, 0.9607],
[0.7006, 0.7421],
[0.4279, 0.9501],
[0.6750, 0.1704],
[0.5777, 0.1154],
[0.5512, 0.3933]]),
tensor([0, 0, 0, 0, 0, 0, 1, 1, 1])])
# 输出结果:
# (111,
# [tensor([[0.3577, 0.3401],
# [0.0156, 0.7550],
# [0.0435, 0.4984],
# [0.1329, 0.5488],
# [0.4330, 0.5362],
# [0.1070, 0.8500],
# [0.1073, 0.2496],
# [0.1733, 0.0226],
# [0.6790, 0.2119]]),
# tensor([1, 0, 0, 0, 0, 0, 0, 1, 1])]) 这里是torch自动将y组合成了一个tensor
class Model(torch.nn.Module):
def __init__(self):
super().__init__()
# 定义神经网络结构
self.fb=torch.nn.Sequential(
# 第一层输入两个,输出32个
torch.nn.Linear(in_features=2,out_features=32),
# 激活层的意思是小于0的数字变为0,即负数归零操作
torch.nn.ReLU(),
# 第二层,输入是32个,输出也是32个
torch.nn.Linear(in_features=32,out_features=32),
# 激活
torch.nn.ReLU(),
# 第三次,输入32个,输出2个
torch.nn.Linear(in_features=32,out_features=2),
# 激活,生成的两个数字相加等于1
torch.nn.Softmax(dim=1)
)
# 定义网络计算过程
def forward(self,x):
return self.fb(x)
model=Model()
# 测试 8行2列的数据,让模型测试,看是否最后输出是否也是8行一列?
model(torch.rand(8,2)).shape
torch.Size([8, 2])
model(torch.tensor([[0.3577, 0.3401]]))
tensor([[0.5228, 0.4772]], grad_fn=)
def train():
#定义优化器,le-4表示0.0004,10的负四次方
opitimizer=torch.optim.Adam(model.parameters(),lr=1e-4)
#定义损失函数 ,一般回归使用mseloss,分类使用celoss
loss_fn=torch.nn.CrossEntropyLoss()
#然后train
model.train()
# 全量数据遍历100轮
for epoch in range(100):
# 遍历loader的数据,循环一次取9条数据,这里注意unpack时,x就是【width,height】
for i,(x,y) in enumerate(loader):
out=model(x)
# 计算损失
loss=loss_fn(out,y)
# 计算损失的梯度
loss.backward()
# 优化参数
opitimizer.step()
# 梯度清零
opitimizer.zero_grad()
# 第二十轮的时候打印一下数据
if epoch % 20 ==0:
# 正确率
# out.argmax(dim=1) 表示哪个值大就说明偏移哪一类,dim=1暂时可以看做是固定的
# (out.argmax(dim=1)==y).sum() 表示的true的个数
acc=(out.argmax(dim=1)==y).sum().item()/len(y)
print(epoch,loss.item(),acc)
torch.save(model,"4.model")
执行的命令:
print(out,“======”,y,“+++++”,(out.argmax(dim=1)==y).sum().item())
print(out.argmax(dim=1),“------------”,(out.argmax(dim=1)==y),“~~~~~~~~~~~”,(out.argmax(dim=1)==y).sum())
输出的结果:
tensor([[9.9999e-01, 1.4671e-05],
[4.6179e-14, 1.0000e+00],
[3.2289e-02, 9.6771e-01],
[1.1237e-22, 1.0000e+00],
[9.9993e-01, 7.0015e-05],
[8.6740e-02, 9.1326e-01],
[1.1458e-18, 1.0000e+00],
[5.2558e-01, 4.7442e-01],
[9.7923e-01, 2.0772e-02]],
grad_fn=) ====== tensor([0, 1, 1, 1, 0, 1, 1, 1, 0]) +++++ 8
tensor([0, 1, 1, 1, 0, 1, 1, 0, 0]) ------------ tensor([ True, True, True, True, True, True, True, False, True]) ~~~~~~~~~~~ tensor(8)
解释:
out.argmax(dim=1) 表示哪个值大就说明偏移哪一类,dim=1暂时可以看做是固定的
(out.argmax(dim=1)==y).sum() 表示的true的个数
a = torch.tensor([[1,2,3],[4,7,6]])
d = a.argmax(dim=1)
print(d)
tensor([2, 1])
train()
80 0.3329530954360962 1.0
80 0.31511250138282776 1.0
80 0.33394935727119446 1.0
80 0.3242819309234619 1.0
80 0.3188716471195221 1.0
80 0.3405844569206238 1.0
80 0.32696405053138733 1.0
80 0.3540787696838379 1.0
80 0.3390745222568512 1.0
80 0.3645476996898651 0.8888888888888888
80 0.3371085822582245 1.0
80 0.31789034605026245 1.0
80 0.31553390622138977 1.0
80 0.3162603974342346 1.0
80 0.35249051451683044 1.0
80 0.3582523465156555 1.0
80 0.3162645995616913 1.0
80 0.37988030910491943 1.0
80 0.34384390711784363 1.0
80 0.31773826479911804 1.0
80 0.3145104646682739 1.0
80 0.31753242015838623 1.0
80 0.3222736120223999 1.0
80 0.38612237572669983 1.0
80 0.35490038990974426 1.0
80 0.34469687938690186 1.0
80 0.34534531831741333 1.0
80 0.31800928711891174 1.0
80 0.34892910718917847 1.0
80 0.33424195647239685 1.0
80 0.37350085377693176 1.0
80 0.3298128843307495 1.0
80 0.3715909719467163 1.0
80 0.3507140874862671 1.0
80 0.33337005972862244 1.0
80 0.3134789764881134 1.0
80 0.35244104266166687 1.0
80 0.3148314654827118 1.0
80 0.3376845419406891 1.0
80 0.3315282464027405 1.0
80 0.3450225591659546 1.0
80 0.3139556646347046 1.0
80 0.34932857751846313 1.0
80 0.3512738049030304 1.0
80 0.3258627951145172 1.0
80 0.3197799324989319 1.0
80 0.358166366815567 0.8888888888888888
80 0.3716268837451935 1.0
80 0.31426626443862915 1.0
80 0.32130196690559387 1.0
80 0.3207002282142639 1.0
80 0.3891155421733856 1.0
80 0.35045987367630005 1.0
80 0.32332736253738403 1.0
80 0.31951677799224854 1.0
80 0.3184094727039337 1.0
80 0.3341224491596222 1.0
80 0.3408585786819458 1.0
80 0.3139263093471527 1.0
80 0.33058592677116394 1.0
80 0.3134475648403168 1.0
80 0.3281571567058563 1.0
80 0.33370518684387207 1.0
80 0.33172252774238586 1.0
80 0.32849007844924927 1.0
80 0.3604048788547516 1.0
80 0.3651810884475708 1.0
# 准备数据
x,fat=next(iter(loader))
x,fat
(tensor([[0.6733, 0.4044],
[0.6503, 0.0303],
[0.9353, 0.9518],
[0.4145, 0.6948],
[0.9560, 0.8009],
[0.6331, 0.0852],
[0.5510, 0.8283],
[0.1402, 0.2726],
[0.3257, 0.8351]]),
tensor([1, 1, 0, 0, 1, 1, 0, 0, 0]))
# 加载模型
modell=torch.load("4.model")
# 使用模型
out=modell(x)
out
tensor([[1.5850e-04, 9.9984e-01],
[1.4121e-06, 1.0000e+00],
[7.1068e-01, 2.8932e-01],
[9.9994e-01, 5.5789e-05],
[4.1401e-03, 9.9586e-01],
[3.3441e-06, 1.0000e+00],
[9.9995e-01, 4.7039e-05],
[9.9111e-01, 8.8864e-03],
[1.0000e+00, 1.5224e-06]], grad_fn=)
out.argmax(dim=1)
tensor([1, 1, 0, 0, 1, 1, 0, 0, 0])
fat
tensor([1, 1, 0, 0, 1, 1, 0, 0, 0])
查看上面out的结果和fat的结论一致,不错