什么是逻辑回归

线性回归预测的是一个连续值,逻辑回归给出的”是”和“否”的回答。逻辑回归用到了一个sigmoid函数,将一个连续的变量映射到概率空间(0~1)。

sigmoid函数是一个概率分布函数 ,给定某个输入,它将输出为一个概率值。

可以把输出值看做一个概率值,这个时候就能用sigmoid激活函数的输出来做分类问题的输出。


当我们输出一个概率值的时候,获得了一个分类输出,那我们如何来做出惩罚呢?或者说如何计算它的损失呢?

前面单变量线性回归的时候,我们使用的是均方误差。即预测值与真实值之间它们差距的平方再求均值。

现在,我们对这个输出添加了一个sigmoid激活函数,使得这种连续输出转变为概率输出,这个时候再使用均方误差输出虽然可以,但是计算量级很小,可能预测结果是0.9,真实值是1,它们之间差距只有0.1,这个值和原数据之间不在真正的一个数量级上。所以,对于分类损失,最好使用交叉熵损失,来增大它的损失。使用交叉熵会输出一个更大的损失,从而对原有的参数做出更大的惩罚(改变),使得它更快的优化。

平方差所惩罚的是与损失为同一数量级的情形,对于分类问题,我们最好的使用交叉熵损失函数会更有效,交叉熵会输出一个更大的“损失”。


交叉熵损失函数

交叉熵刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近。假设概率分布p为期望输出,概率分布q为实际输出,H(p,q)为交叉熵 ,则:


L2就是代表均方误差损失,logistic损失就是交叉熵损失。当实际结果为0,输出为1;实际结果为1,输出为0的时候,经过log运算,会使得损失值非常大。 在计算分类问题的时候,使用交叉熵损失,因为他会放大分类损失的损失值。交叉熵损失也是度量两个概率分布之间距离的时候的一种方法。

在pytorch里,我们使用nn.BCELoss()来计算二元交叉熵

使用信用卡欺诈数据来做逻辑回归

#引入必要的库
import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt# 读取数据集
# 可以看到,它把第一行当成了表头。实际上没有表头,所以要用header=None传参,# header=None表示没有表头。
data = pd.read_csv('../daatset/credit-a.csv',header=None)
data

结果:

可以看到,该数据集一共653行16列。前15列是特征值,第16列是目标(标签) 。


# 前15列是特征,最后一列是输出。data.iloc是pandas的方法,按位置取值
X = data.iloc[:,:-1]
Y = data.iloc[:,-1]
Y.unique() # 查看Y中不重复的元素,二分类,我们想把它分类为0和1

结果:

Y = data.iloc[:,-1].replace(-1,0) # 使用replace 方法将-1替换为0
Y.unique()


数据预处理:

现由于是pandas读取数据,所以取出其中的values转换为numpy的ndarray,再torch.from_numpy转换为tensor。

X = torch.from_numpy(X.values).type(torch.float32) # tensor转换数据类型用 .type 方法。要计算它必须使用float类型
X.shape

结果:

Y.values # 返回的是单个的array,所以需要reshape一下成 653个长度为1的向量,与653个特征一一对应

结果:

Y = torch.from_numpy(Y.values.reshape(-1,1)).type(torch.float32)
Y.shape

结果:


使用nn模块创建模型 ,初始化损失函数、优化方法。

在单线性回归模型中,是使用nn.Linear返回一个模型。今天要做的事情并不是一个单纯的线性模型了,我们要对X中所有的变量初始化一个权重,然后,权重1*特征1、权重2*特征2.......。最后再加一个截距b,这样得到一个值之后,我们还要添加Sigmoid将其映射为一个概率输出,我们在线性回归模型的基础上,把输出加上一个Sigmoid函数,转换为一个概率值,它就变成一个逻辑回归,从而解决二分类问题。这个时候就相当于两个层了,第一个层就是线性层,第二个层就是Sigmoid层。
逻辑回归使用的损失函数:交叉熵损失函数

我们可以使用 nn.sequential() 方法创建模型,它可以将多个层添加在一起形成一个模型。Sequential可以将多个层添加在一起形成一个模型;适用的场景就是顺序连接,也即第一个层的输出交给第二层处理.....

当模型是多个层顺序连接的时候,推荐使用sequentialz这个方法快速创建模型。

from torch import nnmodel = nn.Sequential(# X.shape: torch.Size([653, 15]),每个样本有15个特征,所以Linear的输入长度就是15,输出长度是1nn.Linear(in_features=15,out_features=1), #这个层的输出交给下面的sigmoid层处理nn.Sigmoid()
)loss_fn = nn.BCELoss() # BCELoss是二元交叉熵损失,对应的标签就是0和1这样的标签#   优化函数。SGD是随机梯度下降,它不会考虑前面下降了多少;Adam它会考虑前面下降了多少,对它做加权
opt = torch.optim.Adam(model.parameters(),lr=0.001)    #  torch.optim里面集成了很多优化方法,Adam是最常用的一种优化方法,model

结果:


开始训练:

我们这次训练,不会把这个数据全部的填进去训练,我们只是把这个数据取出一部分进行训练。为什么要这么做?
我们以后最多训练图片或者视频的数据,这些东西比较庞大,假如图片是50g,不可能把这50g图片全部放在模型中训练,需要取出一部分,比如1g进行训练,然后再取1g进行训练,就一个批次一个批次进行训练,我们把这种形式叫做小批次训练,使用batch这个方法。
为什么不一张图片一张图片训练?
会有一个非常大的坏处,这会对异常值极端敏感。假如一张图片是一个异常的值,本来是猫,但是被标成了狗,这个时候模型就会学习到这一点,引起loss剧烈的震荡。

batchSize = 16 # 批次大小
num_batch = 653//batchSize  # 将全部数据训练一遍需要几个批次epoches = 500 # 将全部数据训练500次
for epoch in range(epoches): for batch in range(num_batch): # 把全部数据训练一遍start = batch*batchSizeend = start+batchSizex = X[start:end]y = Y[start:end]y_pred=model(x) # 进行预测。y_pred是一个长度为16的向量,分别是输进去的16个样本的预测值loss = loss_fn(y_pred,y) # 二元交叉熵损失,刻画的是实际输出(概率)与期望输出(概率)的距离# 把模型中所有的变量的grad置为0opt.zero_grad() # 这个方法会把所有需要优化的参数(即初始化时传进去的模型的参数)的梯度置为0loss.backward() # 反向传播,计算每一个变量的梯度opt.step() # 使用优化方法对参数进行优化# 模型的权重和偏执。15个weight,还有一个偏执。
model.state_dict() # 这个模型所做的事情,sigmoid(w1*x1+w2*x2+....+w15*x15+b)

结果:


对于这个模型,我们想知道正确率是个什么情况。
model(X).data.numpy():model(X)是预测值,model(X).data.numpy()取出预测值tensor,对应的data再转换为numpy。

预测结果是一个从0到1之间的小数值,一般选取一个中间值(0.5),将小于0.5的置0,大于0.5的置1。model(X).data.numpy() > 0.5)返回的是一个bool值,可以将bool值转换数据类型,astype是numpy的转换数据类型的方法。

# model(x).data.numpy()返回的是一个概率值,我们认为>0.5就是输出为1,否则输出为0。
(model(X).data.numpy() > 0.5).astype('int') # astype是numpy转换数据类型的方法
(model(X).data.numpy() > 0.5).astype('int') == Y.numpy() # 实际预测结果与真实结果相比较,就能知道出哪个正确哪个错误了
((model(X).data.numpy() > 0.5).astype('int') == Y.numpy()).mean() # 模型正确率

正确率:


多层感知器(神经网络)

上面我们学习的逻辑回归模型是单个神经元:计算输入特征的加权和,然后使用一个激活函数(或传递函数)计算输出。

单个神经元(二分类)

多个神经元(多分类) 

单层神经元的缺陷:

无法拟合“异或”运算;异或 问题看似简单,使用单层的神经元确实没有办法解决。

神经元要求数据必须是线性可分的,但是 异或 问题无法找到一条直线分割两个类,异或问题是线性不可分的问题,使用单个神经元无法拟合它的。 这个问题使得神经网络的发展停滞了很多年,

后来,人们通过生物神经元得到一个启发。生物的神经元一层一层连接起来,当神经信号达到某一个条件,这个神经元就会激活,然后继续传递信息下去。为了继续使用神经网络解决这种不具备线性可分性的问题,采取在神经网络的输入端和输出端之间插入更多的神经元。


这就是多层感知器的概念,也即输入和输出之间插入了隐含层。我们在每一层中间,为了增强它们的拟合能力,会使用一个激活函数(传递函数)。假如说没有传递函数的话,即便是插入了隐含层,这个模型仍然是线性的模型,并不会增加模型的拟合能力;如果没有中间层的激活能力,x1虽然加了那么多权重,但是实际上只是等于x1加了另外一个权重。激活函数就带了了非线性,使得模型的拟合能力大大增强。这样,模型不仅可以处理线性问题,还可以处理更加复杂的多分类问题。这就使得我们的模型拟合能力大大提升。

最常用的就是relu激活:大于0的值原样输出,小于0的值通通输出为0。

其它激活函数:

 在神经网络发展的早期,中间层的激活函数经常使用sigmoid,但是他会带来一个问题。当x很大的时候,它带来的梯度是非常小的,所以我们认为并不是一个很好的激活函数。但是在处理逻辑回归输出的时候,还是要使用sigmoid激活的,因为要输出0~1之间的概率值。

 tanh取值就是在-1~1之间。在处理深层网络的时候,会使用到tanh激活,希望输出被前置到-1~1之间。

leak relu会将负值保留一个小的输出。在GAN训练过程中,对于难以训练问题的时候,一般会使用leak relu对它的生成器当中的参数进行激活。

使用HR数据集来做多层感知器模型

使用HR数据集搭建多层感知器模型,预测一个人近期是否会发生离职。

import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inlinedata = pd.read_csv('../daatset/HR.csv')
data.head() # 返回数据集的前五行。
data.info() # 查看数据集的整体情况信息。

结果:

可以看到,partsalary列的数据类型是object,我们需要转换成数值类型 。


data.part.unique() # 查看有哪些部门。我们要把part这个属性数值化,文本类型不能放到深度学习中进行计算的。
data.salary.unique() # 同样要数值化

结果:


将salary列和part列数值化(独热编码):

pd.get_dummies(data.salary) # 这个方法会将所有的特征数值化,转换成独热编码。
# 比如第一个样本对应的salary是low,现在变成三列,low的那一列就是1,其它两列是0。

data = data.join(pd.get_dummies(data.salary)) #使用join方法,将独热编码形成的新的3列数据加到数据中
del data['salary'] # 删除原有的salary列data = data.join(pd.get_dummies(data.part))
del data['part'] # 删除原有的'part'列

是否会离职就是看数据集中left这一列。看看这一列有多少个0多少个1。

data.left.value_counts() # 值计数。可以看出这并不是均与分布的数据

结果:


11428/len(data) # 即使预测成全部不离职,正确率依然有百分之76。如果我们的模型正确率不能比这个高,那是没有任何意义的。


Y = data.left.values.reshape(-1,1) # reshape成二维数组,Y.shape:(14999, 1)
Y = torch.from_numpy(Y).type(torch.float32) # 转换成tensor数据类型,Y.shape:torch.Size([14999, 1])# 挑选出样本的特征列(除了left,left是标签)
[c for c in data.columns if c!='left'] # 真正的特征那些列(除了left)X = data[[c for c in data.columns if c!='left']].values # pandas数据类型,使用.values返回对应的ndarray数据类型
X = torch.from_numpy(X).type(torch.float32) # 转换成tensorprint(X.shape)
print(Y.shape)

结果:


创建模型 :

本次不使用nn.Sequential直接来创建,我们自定义这个模型 nn模块有一个 nn.Module这个类,我们可以继承自这个类,然后自定义这个模型。 继承这个类之后,只需要在init方法中初始化所有的层,然后在forward方法中进行前向运算,也就是把框架代码搭建起来。

自定义模型:

  • 继承于nn.Module。重写init和forward方法
  • init方法:初始化所有的层
  • forward方法:使用init方法中定义的层,定义前向传播的过程,即模型的运算过程
from torch import nn
import torch.nn.functional as F # functional这个模块为我们内置了很多函数式apiclass Model(nn.Module):def __init__(self):#首先要继承父类中所有的变量super().__init__()# 开始初始化所有的层self.linear1 = nn.Linear(20,64) # 第一个线性层。将输入的20个特征输出到64个特征的隐藏层。self.linear2 = nn.Linear(64,64) # 现在是一个多层感知器,我们要创建两层。self.linear3 = nn.Linear(64,1)  # 输出层。因为是逻辑回归,二分类,所以输出只有一个(0或者1)。self.relu_fn = nn.ReLU()        # 激活函数self.sigmoid_fn = nn.Sigmoid()  # 最后输出层的激活函数,二分类问题的激活函数"""第一个线性层的64个圈会依次和输入的全部特征相连"""'''注意:这里linear1、2、3都有权重和变量,它们都有可训练的参数。但是relu和sigmoid并没有,它们只是对输入做了一个选择,并不需要训练,实际上只是一些方法。可以使用nn.functional来写,这个模块为我们内置了一些函数式api,提供了函数式的调用方法。'''def forward(self,input):# forward方法有一个input参数,你的输入是交给forward方法,然后forward方法调用这些层对输入数据处理。# 线性层1,20 ---> 64x1 = self.linear1(input)x1 = self.relu_fn(x1)# 线性层2,64 ---> 64x2 = self.linear2(x1)x2 = self.relu_fn(x2)# 输出层,64 ----> 1x3 = self.linear3(x2)x3 = self.sigmoid_fn(x3) # 因为这是一个逻辑回归的输出,所以使用sigmoid进行激活。return x3# 改写模型:使用nn.functional来写"""在每一层之间为 了增强拟合能力,在每一层中会使用一个激活函数(传递函数)激活函数就带来了非线性,使得模型的拟合能力大大增强。""""""x = F.relu(self.liner1(input))x = F.relu(self.liner2(x))x = F.sigmoid(self.liner3(x))   # sigmoid将输入映射为0~1之间的概率return  x"""

# 只要初始化Model类,就能拿到这个模型(对象)
model = Model()lr = 0.001 # 学习速率
loss_fn = nn.BCELoss() # 二分类问题,二元交叉熵损失。
batch = 64 # 小批次训练,批次大小是64
num_batches = len(data)//batch # 把全部数据训练一遍需要多少次
epochs = 100 # 把全部数据训练100次
print(num_batches)# 定义一个get_model方法,每一次运行都会得到新的模型以及优化方法,以便将来可以重用
def get_model(lr):model = Model()# 优化器。因为model继承了nn.Module这个类,父类实现了这个方法,所以model.parameters()会返回模型的所有可训练参数opt = torch.optim.Adam(model.parameters(),lr=lr) return model,opt    


开始训练:

model,opt = get_model(0.001)for epoch in range(epochs):for i in range(num_batches):start = i*batchend = start+batch# x和y分别是一个批次的数据x = X[start:end]y = Y[start:end]y_pred = model(x)loss = loss_fn(y_pred,y)opt.zero_grad() # 将所有可训练参数的梯度置为0loss.backward() # 反向传播opt.step() # 优化
#     with torch.no_grad:
#         print('epoch: ',epoch,' ,loss: ',loss_fn(model(X),Y).data.item())# 使用我们训练好的模型进行预测
loss_fn(model(X),Y) # 在整个数据集上的损失值

结果:


利用Dataset类进行重构代码

  • 在上面的训练中,需要对数据X和Y同时进行切片,取出一个批次的数据,这样非常的不方便。PyTorch为我们提供了一个抽象的dataset类。
  • PyTorch有一个抽象的Dataset类。Dataset可以是任何具有__len__魔术方法和__getitem__魔术方法的类,__len和__getitem__是作为对其进行索引的方法的函数。
  • 使用dataset类可以同时对这X和Y进行迭代,PyTorch为我们提供了TensorDataset这个方法可以包装张量,直接将输入和输出包装成一个dataset。一旦包装成一个dataset,我们就可以沿着第一维对这两部分数据同时进行迭代。
  • PyTorch的TensorDataset 是一个包装张量的Dataset。通过定义索引的长度和方式,这也为我们提供了沿张量的第一维进行迭代,索引和切片的方法。这将使我们在训练的同一行中更容易访问自变量和因变量。
from torch.utils.data import TensorDataset
HRdataset = TensorDataset(X,Y)# 将X,Y两个张量包装成一个dataset,就可以沿着第一维对着两部分数据同时进行切片、迭代...# dataset类实现了len方法,可以使用len查看它的长度。
# 实现了__getitem__魔术方法。一旦定义了这个方法,就可以对这个类进行索引和切片。
HRdataset[0] # 返回的是元祖,第一个元素是X中第一个数据的特征(tensor类型),第二个元素是Y中第一个数据的标签

结果:


开始训练 :

model,opt = get_model()
for epoch in range(epochs):for i in range(no_of_batches):x,y = HR_dataset[i*batch:i*batch+batch] # 获取一个批次的特征值和标签值。y_predict = model(x)loss = loss_fn(y_predict,y) # 返回损失(交叉熵)opt.zero_grad() # 将变量的梯度清零。loss.backward() # 反向传播opt.step()  # 优化# 不需要进行梯度运算with torch.no_grad():print("epoch:",epoch," ,loss:",loss_fn(model(X),Y).data.item())  # item是取出单个tensor的值,tensor转numpy

使用dataloader进行重构,方便管理批次

在上面的训练过程中,仍然需要切片,我们能不能够不要切片?
我们还需要注意一个问题,我们每次都是把数据以同样的顺序输入给模型,模型每次看到的都是同一个顺序的数据,它有可能会根据顺序学习到一些东西,我们希望能够乱序的给模型传入数据,让它不要关注数据的顺序而是关注数据的本身。
为了解决上述问题,就可以使用dataloader类进行重构
PyTorch提供了dataloader类来负责管理批次,这样就不用切片来取出每一个批次的数据了,dataloader它会遍历这个批次,从而使得我们遍历整个数据变得容易。Dataloader会自动的为我们提供这样的一个batch,每一个batch每一个batch的数据,不需要切片。DataLoader使遍历批次变得更容易。DataLoader会自动为我们提供每个小批量。

from torch.utils.data import DataLoaderHR_ds = TensorDataset(X,Y)
HR_dl = DataLoader(HR_ds,batch_size = batch,shuffle = True)    # 创建批次。shuffle = True将数据乱序。直接对HR_dl进行迭代,他就会返回每一个批次的数据
model,opt = get_model(0.001)for epoch in range(10):  # 为了加快训练过程,我这里只对全部数据训练10次for x,y in HR_dl:  # 每次都会取出一个批次的数据,直至取完整个数据。y_pred = model(x) # y_pred是经过sigmoid输出的一个介于0~1之间的值loss = loss_fn(y_pred,y)opt.zero_grad() # 将所有可训练参数的梯度置为0loss.backward() # 反向传播opt.step() # 优化with torch.no_grad():# 这一部分的计算不需要跟踪计算print('epoch:',epoch,';loss:',loss_fn(model(X),Y).data.item())

结果:


添加验证,正确率;了解过拟合和欠拟合、划分训练数据集和验证数据集

想知道模型的正确率。
过拟合:对训练数据过度拟合,对于未知数据预测很差
欠拟合:对于训练数据拟合不够,对于未知数据预测很差
将全部数据集分为训练数据集和测试数据集

前面我们只是试图建立一个合理的训练循环以用于我们的训练数据。实际上,您始终还应该具有一个验证集,以识别您是否过度拟合。
训练数据的乱序(shuffle)对于防止批次与过度拟合之间的相关性很重要。
另一方面,无论我们是否对验证集做乱序,验证损失都是相同的。由于shufle需要额外的开销,因此shuffle验证数据集没有任何意义。
我们将为验证集使用批大小,该批大小是训练集的两倍。这是因为验证集不需要反向传播,因此占用的内存更少(不需要存储梯度)。我们利用这一优势来使用更大的批量,并更快地计算损失。

数据集的划分:

from sklearn.model_selection import train_test_split# 在这里,使用ndarray数据进行划分
X_data = data[[c for c in data.columns if c!='left']].values
Y_data = data.left.values.reshape(-1,1)train_X,test_X,train_Y,test_Y = train_test_split(X_data,Y_data)
train_X.shape[0]/X_data.shape[0] # 结果是0.75,即百分之75拿来做训练数据集# X_train,X_test,y_train,y_test现在仍是ndarray形式,需要转换为tensor形式才能包装成dataset
# 进行反向传播运算,要求数据类型必须是float数据类型
train_X = torch.from_numpy(train_X).type(torch.float32)
train_Y = torch.from_numpy(train_Y).type(torch.float32)
test_X = torch.from_numpy(test_X).type(torch.float32)
test_Y = torch.from_numpy(test_Y).type(torch.float32)#包装成Dataloader
train_ds = TensorDataset(train_X,train_Y)
train_dl = DataLoader(train_ds,batch_size=batch,shuffle=True)test_ds = TensorDataset(test_X,test_Y)
test_dl = DataLoader(test_ds,batch_size=batch) # 对于测试数据没有必要做shuffle

如何计算正确率 :

现在咱门模型的预测输出是一个sigmoid函数的输出值(二分类),介于0~1之间,如何把这个输出值翻译为0和1呢?因为我们的目标值已经被编码为0和1了。实际上一般的做法是选取一个中间值(0.5),大于0.5的就认为我们模型的预测结果是1,否则就是0。

实际预测结果:y_pred=(y_pred>0.5).type(torch.int32)

正确率:(y_pred==y).float().mean()。.float()是将true转变为1,false转变为0

# 计算正确率的函数
def accuracy(y_pred,y_true):y_true=y_true.int()y_pred = (y_pred>0.5).type(torch.int32)acc = (y_pred == y_true).float().mean()return accmodel.opt = get_model(0.001)

开始训练: 

for epoch in range(epochs):  # 为了加快训练过程,我这里只对全部数据训练10次for x,y in train_dl:y_pred = model(x) # y_pred是经过sigmoid输出的一个介于0~1之间的值loss = loss_fn(y_pred,y)opt.zero_grad() # 将所有可训练参数的梯度置为0loss.backward() # 反向传播opt.step() # 优化参数with torch.no_grad():# 这一部分的计算不需要跟踪计算epoch_acc = accuracy(model(train_X),train_Y) #每一个批次,对全部数据进行预测,得到的平均正确率epoch_loss = loss_fn(model(train_X),train_Y).data epoch_test_acc =  accuracy(model(test_X),test_Y)epoch_test_loss = loss_fn(model(test_X),test_Y).data # 使用 .item 将单个的tensor输出值转化为了python的标量值print("epoch:%d"%epoch)print("loss:",round(epoch_loss.item(),3),",accuracy:",round(epoch_acc.item(),3))print("test_loss:",round(epoch_test_loss.item(),3),",test_accuracy:",round(epoch_test_acc.item(),3))print("——————————————————————————————")print(loss_fn(model(X),Y))  # 训练完毕之后,在所有的参数上的loss损失情况

结果:

PyTorch 03—逻辑回归与多层感知器相关推荐

  1. ML:基于自定义数据集利用Logistic、梯度下降算法GD、LoR逻辑回归、Perceptron感知器、SVM支持向量机、LDA线性判别分析算法进行二分类预测(决策边界可视化)

    ML:基于自定义数据集利用Logistic.梯度下降算法GD.LoR逻辑回归.Perceptron感知器.支持向量机(SVM_Linear.SVM_Rbf).LDA线性判别分析算法进行二分类预测(决策 ...

  2. 神经网络入门回顾(感知器、多层感知器)

    神经网络属于"联结主义",和统计机器学习的理论基础区别还是很不一样. 以我自己的理解,统计机器学习的理论基于统计学,理论厚度足够强,让人有足够的安全感:而神经网络的理论更侧重于代数 ...

  3. 逻辑斯第回归、softmax分类与多层感知器

    本专栏将推出一系列深度学习与图像处理相关的教程文章.注重原理精讲和代码实现.实现框架将重点选择Tensorflow或Pytorch.本讲从逻辑斯第回归入手,然后讲解softmax分类器,最后讲解多层感 ...

  4. 感知器的c++实现_使用FastAI和PyTorch的多层感知器

    我将向您展示如何使用FastAIv1和Pytorch构建神经网络(多层感知器)并成功训练它以识别图像中的数字.Pytorch是一个非常流行的深度学习框架,FastAI v1是一个使用现代最佳实践简化训 ...

  5. 使用pytorch搭建MLP多层感知器分类网络判断LOL比赛胜负

    使用pytorch搭建MLP多层感知器分类网络判断LOL比赛胜负 1. 数据集 百度网盘链接,提取码:q79p 数据集文件格式为CSV.数据集包含了大约5万场英雄联盟钻石排位赛前15分钟的数据集合,总 ...

  6. 翻译: 4.多层感知器 pytorch

    在本章中,我们将介绍您的第一个真正深入的网络.最简单的深度网络称为多层感知器,它们由多层神经元组成,每一层都与下层(它们接收输入)和上层(它们反过来影响)中的神经元完全连接.当我们训练高容量模型时,我 ...

  7. 深度学习入门系列1:多层感知器概述

    本人正在学习<deep learning with python>–Jason Brownlee,有兴趣的可以一起学习. 仅供学习参考,不做商用! 大家好,我技术人Howzit,这是深度学 ...

  8. 深度学习(一)多层感知器MLP/人工神经网络ANN

    目录 一.定义和公式 1. 多层感知器 Multi Layer Perceptron MLP 2. MLP实现非线性分类 3. Keras介绍 二. 代码实战 1. 建立MLP模型实现二分类 1.1  ...

  9. 多层感知器(MLP)

    多层感知器 多层感知器(Multilayer Perceptron,缩写MLP)是一种前向结构的人工神经网络,映射一组输入向量到一组输出向量.MLP可以被看作是一个有向图,由多个的节点层所组成,每一层 ...

最新文章

  1. python电路模型编程_14、python开发之路-并发编程之I/O模型
  2. Caching Best Practices--reference
  3. 兼顾隐私与权利,华为以“科技有道”,实现“隐私无价”
  4. 【DotNetMLLearn】.NET Core人工智能系列-概述
  5. [deviceone开发]-do_Album的简单示例
  6. Taro+react开发(89):封装为一个函数渲染
  7. OpenCV中HoughLinesP( )检测直线函数返回的坐标的原点
  8. 编写一个watchdog.sh脚本_拍摄Vlog,如何构思和编写脚本?
  9. 请求重定向与请求转发的比较(HttpServletResponse.sendRedirect方法和RequestDispatcher.forward方法)...
  10. 前端面试题大集合:来自真实大厂的532道面试题(只有题,没有答案)
  11. 我的ActiveRecord学习之路(一)
  12. java中伪代码_问Java的伪代码怎么书写
  13. YII学习笔记6.20日
  14. 初级程序员面试题总结(一):
  15. 华为云redis安装
  16. 【二分答案】Problem A:天堂_珍珠
  17. However的用法主要有以下两点:
  18. 传统企业数字化转型方案
  19. STM32 GPS定位
  20. 对称密钥算法和公钥算法的优缺点

热门文章

  1. 淘宝装修教程 淘宝美工教程 淘宝教程 淘宝美工职业之路
  2. ED80/6电力液压推动器
  3. php伪静态网前台页面,如何让Discuz门户频道页支持伪静态
  4. YUV12和YUV2格式
  5. 建筑与建筑群综合布线系统工程施工及验收规范
  6. 《SDD-CNN: Small Data-Driven Convolution Neural》--翻译笔记
  7. glade java_Say Hello to Glade
  8. 在WPF中制作正圆形公章
  9. 如何使用Origin绘制两点线段图
  10. DROID-SLAM: 单目、双目、RGBD相机的深度视觉SLAM