Pytorch3_搭建网络实现FizzBuzz小游戏

1.固定结构

  •   #搭建前向网络
      class Net(torch.nn.Module):
      	def __init__(self,input_features,hidden_nums,output_features):
     		 	super(Net,self).__init__()
      				……
      				…网络结构:Linear、Conv…
      				……
    
      	def forward(self,x):
      		调用上边的网络结构
      		#return 返回值
            return x
    
  •   #调用神经网络,传入网络层的参数
      net = Net(10,100,4)
    
  •   #定义优化器,传入:net网络的所有参数,学习率
      optimizer = torch.optim.SGD(net.parameters(),lr = 0.05)
    
  •   #定义损失函数
      loss_func = torch.nn.CrossEntropyLoss()  #此例使用交叉熵
    
  •   #开始迭代
      for iterate in range(1,10001):
      
      		#预测值
      		predict = net(……)
    
     		 #计算损失
      		loss = loss_func(predict,…GroundTruth…)
    
      		#优化三部曲:清0—>反向传播—>更新
      		optimizer.zero_grad()
      		loss.backward()
      		optimizer.step()
    

2. 是否使用with torch.no_grad()——两者计算的结果实际上是没有区别的

  • 使用with torch.no_grad():,强制之后的内容不进行计算图构建

  • 不使用with torch.no_grad():有grad_fn=属性,表示,计算的结果在一计算图当中,可以进行梯度反传等操作。

  • 主要是在测试集中,使用with torch.no_grad(),因为此时不再进行反向传播更新参数
    执行结果:
    在这里插入图片描述

测试
testX = torch.Tensor([binary_encode(i, NUM_DIGITS) for i in range(1, 101)])

with torch.no_grad():
	 测试结果存放在testY中
    testY = net(testX)
    print(testY.shape)
    print("1-*-*-*-*-*-1-*-*-*-*-*-1")

predictions = zip(range(1, 101), list(testY.max(1)[1].data.tolist()))
print([fizz_buzz_decode(i, x) for (i, x) in predictions])
print("预测正确个数:",sum(  testY.max(1)[1].data.tolist() == np.array([fizz_buzz_encode(i) for i in range(1,101)])  ) )

3.完整程序:搭建神经网络实现FizzBuzz游戏
在这里插入图片描述

import torch
import numpy as np
import torch.nn.functional as F



def fizz_buzz_encode(i):
    if (i % 15 == 0):
        return 3
    elif (i % 5 == 0):
        return 2
    elif (i % 3 == 0):
        return 1
    else:
        return 0


def fizz_buzz_decode(i, prediction):
    #当前数字i由str(i)
    # 转换成字符串,
    # prediction代表的数,来控制输出字符串中的哪一个
    return [str(i), "fizz", "buzz", "fizzbuzz"][prediction]


#控制二进制数的长度为10
NUM_DIGITS = 10

	#十进制数据转换成2进制数据,故意搞混乱让软件自己去学出规律
def binary_encode(i,num_digits):
   	#移位取出i的二进制位
    return np.array([i>>d & 1  for d in range(num_digits)])

#训练集数据
trX = torch.Tensor([binary_encode(i,NUM_DIGITS) for i in range(101,2**NUM_DIGITS)])
#对应正确数据集
trY = torch.LongTensor([fizz_buzz_encode(i) for i in range(101,2**NUM_DIGITS)])





#搭建前向网络
class Net(torch.nn.Module):
    def __init__(self,input_features,hidden_nums,output_features):
        super(Net,self).__init__()

        self.hiddenNet1 = torch.nn.Linear(input_features,hidden_nums)
        self.prediction = torch.nn.Linear(hidden_nums,output_features)

    def forward(self,x):
        x = F.relu(self.hiddenNet1(x))
        x = self.prediction(x)

        return x





#调用神经网络
net = Net(10,100,4)

#定义优化器,传入:net网络的所有参数,学习率
optimizer = torch.optim.SGD(net.parameters(),lr = 0.05)
#定义损失函数
loss_func = torch.nn.CrossEntropyLoss()  #使用均方误差

#开始迭代
BATCH_SIZE=128
for iterate in range(1,10001):
    for start in range(0, len(trX), BATCH_SIZE):

        end = start + BATCH_SIZE
        # 取出trX的128行
        batch_X = trX[start:end]
        # 取出trY的128行
        batch_Y = trY[start:end]

        #预测值
        predict = net(batch_X)

        #计算损失
        loss = loss_func(predict,batch_Y)

        #优化三部曲:清0—>反向传播—>更新
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    loss = loss_func(net(trX), trY).item()
    if iterate % 100 == 0 :
        print("Train Epoch:{}:{}".format(
            iterate,
            loss
        ))




#测试
testX = torch.Tensor([binary_encode(i, NUM_DIGITS) for i in range(1, 101)])

with torch.no_grad():
	# 测试结果存放在testY中
    testY = net(testX)
    print(testY.shape)
    print("1-*-*-*-*-*-1-*-*-*-*-*-1")

# 把1维数组[1~100]和testY的每行4个元素中最大的那个的坐标通过zip压缩在一起

predictions = zip(range(1, 101), list(testY.max(1)[1].data.tolist()))
# 输出预测结果
print([fizz_buzz_decode(i, x) for (i, x) in predictions])


#通过.numpy()、.tolist()或.data.tolist(),转换成数组进行比较
#通过sum()或者np.sum(),对比较后的数组进行求和,看看有几个是计算对的
print("预测正确个数:",sum(  testY.max(1)[1].data.tolist() == np.array([fizz_buzz_encode(i) for i in range(1,101)])  ) )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值