事前  :

kaggle地址:ML2021Spring-hw1 | Kaggle

我的git地址: https://github.com/xiaolilaoli/lihongyi2022homework/tree/main/hw1_covidpred

当然作为新手,我也是参考的其他大神的。参考的过多,我就不一一放地址了,在这里谢过各位大佬。如果和我一样的新手,调试代码看张量流动绝对是一个好用的方法。

作业介绍: 说的是啊 这个美国,好像是有40个州, 这四十个州呢 ,统计了连续三天的新冠阳性人数,和每天的一些社会特征,比如带口罩情况, 居家办公情况等等。现在有一群人比较坏,把第三天的数据遮住了,我们就要用前两天的情况以及第三天的特征,来预测第三天的阳性人数。但幸好的是,我们还是有一些数据可以作为参考的,就是我们的训练集。

  一: 数据读取。

(第一步引用的包:)

  1. import numpy as np
  2. from torch.utils.data import Dataset,DataLoader
  3. import csv
  4. import torch
  5. from sklearn.feature_selection import SelectKBest
  6. from sklearn.feature_selection import chi2

先从kaggle上把数据下下来看看。点那个data就找到下载的地方了。下载好数据第一步先观察train的数据是什么样子的。如下图,可以看到有很多列,每一列都是一类特征,每一行都是一个样本。黄红蓝是第1,2,3天的测试阳性数据。蓝色的就是我们要预测的值啦。

我们再细看数据: 可以看到第一行是没有用的,他只是标签的名称。然后第一列也是没有用处的,因为他只是标注样本是第几个样本。等会处理数据时都要处理掉。 然后我们可以注意到前40列的数据和后面五十多列是不一样的,一般是一列全1 其他列全0 ,表示的是1所在的那个州,地点标识而已。

看清楚数据的结构,下面我们开始读入数据。csv数据和其他数据的读法差不多。比如你可以选择下面的文件式读法。

  1. with open(r'covid.train.csv', 'r') as f:
  2. train_data = f.readlines()
  3. train_data = [line.split('\n') for line in train_data][1:] #分行之后不要第一行
  4. train_data = [each[0].split(',') for each in train_data] #对于每一行 去掉后面的空格
  5. print(len(train_data[0]))
  6. train_data = np.array(train_data) #转换成numpy的矩阵
  7. train_x = train_data[:,1:-1] # x是数据,y是标签 。第一个冒号表示所有行,第二个冒号表示
  8. train_y = train_data[:,-1] #列。所以x就是第2列到倒数第二列。y就是倒数第一列。

也可以选择csv的专门读取excel表格的函数

  1. with open(path,'r') as f:
  2. csv_data = list(csv.reader(f))
  3. column = csv_data[0] #0行是标题
  4. csv_data = np.array(csv_data[1:])[:,1:].astype(float) #连环操作 先取行 转numpy
  5. #再取列 转float

然后这里要介绍一个取最相关列的操作。 上面的数据我们知道有95列,可是,这90多列,每一列都与结果是相关的吗? 恐怕不一定,肯定有些特征卵用没有。所以我们这里可以找到那些相关的列,用这些特征来预测结果。找特征有很多方法,大家可以百度特征选择,有很多介绍。这里用的是SelectKBest 函数。顺便定义了一个挑特征的函数。column是第一行的特征名称,我传入是为了打印看看是哪些特征重要,要不然他挑了半天我也不知道啊 。k是挑多少个特征。


  1. def get_feature_importance(feature_data, label_data, k =4,column = None):
  2. """
  3. 此处省略 feature_data, label_data 的生成代码。
  4. 如果是 CSV 文件,可通过 read_csv() 函数获得特征和标签。
  5. """
  6. model = SelectKBest(chi2, k=k)#选择k个最佳特征
  7. X_new = model.fit_transform(feature_data, label_data)
  8. #feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征
  9. print('x_new', X_new)
  10. scores = model.scores_
  11. # 按重要性排序,选出最重要的 k 个
  12. indices = np.argsort(scores)[::-1] #找到重要K个的下标
  13. if column:
  14. k_best_features = [column[i+1] for i in indices[0:k].tolist()]
  15. print('k best features are: ',k_best_features)
  16. return X_new, indices[0:k]

找好特征后。我们还需要进行训练集和验证集的划分。 我们知道,kaggle下下来只有训练集和测试集,所以我们需要从训练集里分出来一个验证集来作为模型评价。 方法可以是直接截一段,也可以是逢几个挑一个,也可以是随机的。我这里是逢5挑1

  1. if mode == 'train':
  2. indices = [i for i in range(len(csv_data)) if i % 5 != 0]
  3. self.y = torch.LongTensor(csv_data[indices,-1])
  4. elif mode == 'val':
  5. indices = [i for i in range(len(csv_data)) if i % 5 == 0]
  6. # data = torch.tensor(csv_data[indices,col_indices])
  7. self.y = torch.LongTensor(csv_data[indices,-1])
  8. else:
  9. indices = [i for i in range(len(csv_data))]
  10. #这是测试数据 不需要标签 也没有标签

取完数据后,一般还要有一个归一化的步骤,防止各个特征的数量级相差过于大。这里用的是Z-score标准化方法。减均值除以标准差

  1. self.data = (self.data - self.data.mean(dim=0,keepdim=True))
  2. /self.data.std(dim=0,keepdim=True) #这里将数据归一化。

综上所述,我们可以写出我们的dataset函数了。基本上大部分神经网络都是需要读数据这部分的,过程就是把数据从本地文件,读入dataset中去。dataset中一般有三个函数,第一个是初始化__init__:  一般负责把数据从文件取出来。第二个获取数据__getitem__, 负责读第几个数据。第三个获取长度__len__: 负责返回数据集的长度。

一个完整的从csv到可以用的dataset的 代码如下图所示。 这一部分被我放在model——utils的data模块里。

完整代码:

  1. import numpy as np
  2. from torch.utils.data import Dataset,DataLoader
  3. import csv
  4. import torch
  5. from sklearn.feature_selection import SelectKBest
  6. from sklearn.feature_selection import chi2
  7. def get_feature_importance(feature_data, label_data, k =4,column = None):
  8. """
  9. 此处省略 feature_data, label_data 的生成代码。
  10. 如果是 CSV 文件,可通过 read_csv() 函数获得特征和标签。
  11. """
  12. model = SelectKBest(chi2, k=k)#选择k个最佳特征
  13. X_new = model.fit_transform(feature_data, label_data)
  14. #feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征
  15. print('x_new', X_new)
  16. scores = model.scores_
  17. # 按重要性排序,选出最重要的 k 个
  18. indices = np.argsort(scores)[::-1] #找到重要K个的下标
  19. if column:
  20. k_best_features = [column[i+1] for i in indices[0:k].tolist()]
  21. print('k best features are: ',k_best_features)
  22. return X_new, indices[0:k]
  23. class covidDataset(Dataset):
  24. def __init__(self, path, mode, feature_dim):
  25. with open(path,'r') as f:
  26. csv_data = list(csv.reader(f))
  27. column = csv_data[0]
  28. train_x = np.array(csv_data)[1:][:,1:-1]
  29. train_y = np.array(csv_data)[1:][:,-1]
  30. _,col_indices = get_feature_importance(train_x,train_y,feature_dim,column)
  31. col_indices = col_indices.tolist() #得到重要列的下标
  32. csv_data = np.array(csv_data[1:])[:,1:].astype(float)
  33. if mode == 'train': #如果读的是训练数据 就逢5取4 indices是数据下标
  34. indices = [i for i in range(len(csv_data)) if i % 5 != 0]
  35. self.y = torch.LongTensor(csv_data[indices,-1])
  36. elif mode == 'val': #如果读的是验证数据 就逢5取1 indices是数据下标
  37. indices = [i for i in range(len(csv_data)) if i % 5 == 0]
  38. # data = torch.tensor(csv_data[indices,col_indices])
  39. self.y = torch.LongTensor(csv_data[indices,-1])
  40. else: #如果读的是测试数据 就全取了
  41. indices = [i for i in range(len(csv_data))]
  42. data = torch.tensor(csv_data[indices,:]) #取行
  43. self.data = data[:,col_indices] #取列
  44. self.mode = mode
  45. self.data = (self.data - self.data.mean(dim=0,keepdim=True)) /self.data.std(dim=0,keepdim=True) #这里将数据归一化。
  46. assert feature_dim == self.data.shape[1]
  47. print('Finished reading the {} set of COVID19 Dataset ({} samples found, each dim = {})'
  48. .format(mode, len(self.data), feature_dim))
  49. def __getitem__(self, item):
  50. if self.mode == 'test':
  51. return self.data[item].float()
  52. else :
  53. return self.data[item].float(), self.y[item]
  54. def __len__(self):
  55. return len(self.data)

二 模型设计。

数据都读完了,接下来肯定是模型了 。当然这里是一个简单的回归模型我用两个全连接实现的,中间加了一个relu。inDim是传入的参数 ,就是上面我们挑选的重要特征的数量啦。这部分比较简单,一般模型都是包括这两个部分 __init__和forward  也就是初始化和前向传播。初始化中会定义前向传播里需要的模型模块。前向传播里就是输入到输出的流动了 。x是输入的张量,最后输出模型计算结果。 模型也非常简单。

注意网络一般都是按batch大小计算的。我举个例子。 假如我挑了4个特征,那么模型输入长度就是4,输出长度就是1(回归值) 。假如我16个数据1批次, 输入大小就是(16,4) 输出就是(16,1) 这都是自动的 不用我们担心。这一部分被我放在model_utils的model模块里。

完整代码:

  1. import torch.nn as nn
  2. class myNet(nn.Module):
  3. def __init__(self,inDim):
  4. super(myNet,self).__init__()
  5. self.fc1 = nn.Linear(inDim, 64)
  6. self.relu = nn.ReLU()
  7. self.fc2 = nn.Linear(64,1)
  8. def forward(self, x):
  9. x = self.fc1(x)
  10. x = self.relu(x)
  11. x = self.fc2(x)
  12. if len(x.size()) > 1:
  13. return x.squeeze(1) #如果批量大小不为1 这里才需要展平。
  14. else:
  15. return x

三   训练步骤。

训练函数推荐大家自己定义一个的,这样以后面对大部分问题都可以通用。

这个是训练的过程 都是很常规的步骤。

  1. for i in range(epoch):
  2. start_time = time.time()
  3. model.train() #开启训练
  4. train_loss = 0.0
  5. val_loss = 0.0
  6. for data in trainloader:
  7. optimizer.zero_grad()
  8. x , target = data[0].to(device), data[1].to(torch.float32).to(device)
  9. #从loader里取一批数据
  10. pred = model(x) #经过模型预测
  11. bat_loss = loss(pred, target, model) #计算loss
  12. bat_loss.backward() #梯度回传
  13. optimizer.step() #计算
  14. train_loss += bat_loss.detach().cpu().item() #记录loss值 注意要从gpu上取下来
  15. #再从张量里取出来
  16. plt_train_loss . append(train_loss/trainset.__len__()) #记录

每一个epoch里还有验证步骤。参照训练可以看到每一步的作用。多了一个保存模型的步骤。保存loss最低时的那个模型。

  1. model.eval()
  2. with torch.no_grad():
  3. for data in valloader:
  4. val_x , val_target = data[0].to(device), data[1].to(device)
  5. val_pred = model(val_x)
  6. val_bat_loss = loss(val_pred, val_target, model)
  7. val_loss += val_bat_loss
  8. val_rel.append(val_pred)
  9. if val_loss < min_val_loss:
  10. min_val_loss = val_loss
  11. torch.save(model, save_)
  12. plt_val_loss . append(val_loss/valloader.__len__())

还有绘图: 画出loss的变化情况。

  1. plt.plot(plt_train_loss)
  2. plt.plot(plt_val_loss)
  3. plt.title('loss')
  4. plt.legend(['train', 'val'])
  5. plt.show()

完整的训练代码:这一部分被我放在model_utils的train模块里。


  1. import torch
  2. import time
  3. import matplotlib.pyplot as plt
  4. def train_val(model, trainloader, valloader,optimizer, loss, epoch, device, save_):
  5. # trainloader = DataLoader(trainset,batch_size=batch,shuffle=True)
  6. # valloader = DataLoader(valset,batch_size=batch,shuffle=True)
  7. model = model.to(device)
  8. plt_train_loss = []
  9. plt_val_loss = []
  10. val_rel = []
  11. min_val_loss = 100000
  12. for i in range(epoch):
  13. start_time = time.time()
  14. model.train()
  15. train_loss = 0.0
  16. val_loss = 0.0
  17. for data in trainloader:
  18. optimizer.zero_grad()
  19. x , target = data[0].to(device), data[1].to(torch.float32).to(device)
  20. pred = model(x)
  21. bat_loss = loss(pred, target, model)
  22. bat_loss.backward()
  23. optimizer.step()
  24. train_loss += bat_loss.detach().cpu().item()
  25. plt_train_loss . append(train_loss/trainloader.__len__())
  26. model.eval()
  27. with torch.no_grad(): #验证时 不计算梯度
  28. for data in valloader:
  29. val_x , val_target = data[0].to(device), data[1].to(device)
  30. val_pred = model(val_x)
  31. val_bat_loss = loss(val_pred, val_target, model)
  32. val_loss += val_bat_loss
  33. val_rel.append(val_pred)
  34. if val_loss < min_val_loss:
  35. torch.save(model, save_)
  36. min_val_loss = val_loss
  37. plt_val_loss . append(val_loss/valloader.__len__())
  38. print('[%03d/%03d] %2.2f sec(s) TrainLoss : %3.6f | valLoss: %3.6f' % \
  39. (i, epoch, time.time()-start_time, plt_train_loss[-1], plt_val_loss[-1])
  40. )
  41. plt.plot(plt_train_loss)
  42. plt.plot(plt_val_loss)
  43. plt.title('loss')
  44. plt.legend(['train', 'val'])
  45. plt.show()

四:测试和保存步骤 。

测试和验证时很相似的。 少的是预测值和真值的比较,因为没有真值 ,多的是预测值得保存。按照kaggle要求保存在csv里 。这一部分被我放在model_utils的evaluate模块里。

完整代码:

  1. import numpy as np
  2. import torch
  3. from torch.utils.data import DataLoader
  4. import csv
  5. def evaluate(model_path, testset, rel_path ,device):
  6. model = torch.load(model_path).to(device)
  7. testloader = DataLoader(testset,batch_size=1,shuffle=False) #放入loader 其实可能没必要 loader作用就是把数据形成批次而已
  8. val_rel = []
  9. model.eval()
  10. with torch.no_grad():
  11. for data in testloader:
  12. x = data.to(device)
  13. pred = model(x)
  14. val_rel.append(pred.item())
  15. print(val_rel)
  16. with open(rel_path, 'w') as f:
  17. csv_writer = csv.writer(f) #百度的csv写法
  18. csv_writer.writerow(['id','tested_positive'])
  19. for i in range(len(testset)):
  20. csv_writer.writerow([str(i),str(val_rel[i])])

五 : 主函数。

万事俱备,只欠东风。就像人的四肢脑袋都齐了,就差个body把他们连起来了,起这个作用的 就是main函数。

调包第一步 除了系统包 还有自己写的

  1. from model_utils.model import myNet
  2. from model_utils.data import covidDataset
  3. from model_utils.train import train_val
  4. from model_utils.evaluate import evaluate
  5. from torch import optim
  6. import torch.nn as nn
  7. import torch
  8. from torch.utils.data import Dataset,DataLoader

路径和设备 以及一些超参。 在这里 我尝试将一些超参放入字典中。

  1. device = 'cuda' if torch.cuda.is_available() else 'cpu' #设备一般gpu 没有就cpu
  2. train_path = 'covid.train.csv' #训练数据路径
  3. test_path = 'covid.test.csv' #测试数据路径
  4. feature_dim = 6 #重要的特征数
  5. trainset = covidDataset(train_path,'train',feature_dim=feature_dim)
  6. valset = covidDataset(train_path,'val',feature_dim=feature_dim)
  7. testset = covidDataset(test_path,'test',feature_dim=feature_dim)
  8. #对照数据部分 读取了三个数据set
  9. config = {
  10. 'n_epochs': 2000, # maximum number of epochs
  11. 'batch_size': 270, # mini-batch size for dataloader
  12. 'optimizer': 'SGD', # optimization algorithm (optimizer in torch.optim)
  13. 'optim_hparas': { # hyper-parameters for the optimizer (depends on which optimizer you are using)
  14. 'lr': 0.0001, # learning rate of SGD
  15. 'momentum': 0.9 # momentum for SGD
  16. },
  17. 'save_path': 'model_save/model.pth', # your model will be saved here
  18. }
  19. #一些超参数 比如epoch batchsize lr 等等。

定义loss  这里采用了mseloss 然后还加上了正则化

  1. def getLoss(pred, target, model):
  2. loss = nn.MSELoss(reduction='mean')
  3. ''' Calculate loss '''
  4. regularization_loss = 0
  5. for param in model.parameters():
  6. # 使用L2正则项
  7. regularization_loss += torch.sum(param ** 2)
  8. return loss(pred, target) + 0.00075 * regularization_loss
  9. loss = getLoss

定义model和优化器 以及数据传入loader 前面说过这是为了批量处理

  1. model = myNet(feature_dim).to(device)
  2. optimizer = optim.SGD(model.parameters(), lr=0.001,momentum=0.9)
  3. trainloader = DataLoader(trainset,batch_size=config['batch_size'],shuffle=True)
  4. valloader = DataLoader(valset,batch_size=config['batch_size'],shuffle=True)

训练和测试


  1. train_val(model, trainloader,valloader,optimizer, loss, config['n_epochs'],device,save_=config['save_path'])
  2. evaluate(config['save_path'], testset, 'pred.csv',device)

完整代码:

  1. from model_utils.model import myNet
  2. from model_utils.data import covidDataset
  3. from model_utils.train import train_val
  4. from model_utils.evaluate import evaluate
  5. from torch import optim
  6. import torch.nn as nn
  7. import torch
  8. from torch.utils.data import Dataset,DataLoader
  9. device = 'cuda' if torch.cuda.is_available() else 'cpu'
  10. train_path = 'covid.train.csv'
  11. test_path = 'covid.test.csv'
  12. feature_dim = 6
  13. trainset = covidDataset(train_path,'train',feature_dim=feature_dim)
  14. valset = covidDataset(train_path,'val',feature_dim=feature_dim)
  15. testset = covidDataset(test_path,'test',feature_dim=feature_dim)
  16. config = {
  17. 'n_epochs': 2000, # maximum number of epochs
  18. 'batch_size': 270, # mini-batch size for dataloader
  19. 'optimizer': 'SGD', # optimization algorithm (optimizer in torch.optim)
  20. 'optim_hparas': { # hyper-parameters for the optimizer (depends on which optimizer you are using)
  21. 'lr': 0.0001, # learning rate of SGD
  22. 'momentum': 0.9 # momentum for SGD
  23. },
  24. 'early_stop': 200, # early stopping epochs (the number epochs since your model's last improvement)
  25. 'save_path': 'model_save/model.pth', # your model will be saved here
  26. }
  27. def getLoss(pred, target, model):
  28. loss = nn.MSELoss(reduction='mean')
  29. ''' Calculate loss '''
  30. regularization_loss = 0
  31. for param in model.parameters():
  32. # TODO: you may implement L1/L2 regularization here
  33. # 使用L2正则项
  34. # regularization_loss += torch.sum(abs(param))
  35. regularization_loss += torch.sum(param ** 2)
  36. return loss(pred, target) + 0.00075 * regularization_loss
  37. loss = getLoss
  38. model = myNet(feature_dim).to(device)
  39. optimizer = optim.SGD(model.parameters(), lr=0.001,momentum=0.9)
  40. trainloader = DataLoader(trainset,batch_size=config['batch_size'],shuffle=True)
  41. valloader = DataLoader(valset,batch_size=config['batch_size'],shuffle=True)
  42. train_val(model, trainloader,valloader,optimizer, loss, config['n_epochs'],device,save_=config['save_path'])
  43. evaluate(config['save_path'], testset, 'pred.csv',device)

事后:

运行主函数 我们将得到 pred.csv。这就是我们得预测结果啦。打开kaggle网址项目所在页, 注册,点击late submission 提交你的pred.csv文件吧。 这也是我第一次用kaggle。 好像我的得分也很低。大家如果想得一个比较高得分,可以多调调超参和模型。fighting!!!

李宏毅老师前年课程的第一个作业也是回归,不过不是新冠。当时我啥都不会写,把网上得copy下来,一步一步调试才慢慢懂一点点。 这次第二次做回归,只能说比第一次熟练了很多,虽然还是不能全部一个人写下来。 写这个文章,与大家共勉。

2022李宏毅作业hw1—新冠阳性人员数量预测。的更多相关文章

  1. Python小白的数学建模课-A3.12 个新冠疫情数模竞赛赛题与点评

    新冠疫情深刻和全面地影响着社会和生活,已经成为数学建模竞赛的背景帝. 本文收集了与新冠疫情相关的的数学建模竞赛赛题,供大家参考,欢迎收藏关注. 『Python小白的数学建模课 @ Youcans』带你 ...

  2. 参加Folding@Home(FAH)项目,为战胜新冠肺炎贡献出自己的一份力量

    鉴于新冠病毒(COVID-19)在全球范围内的大规模传播,PCMR和NVIDIA呼吁全球PC用户加入Folding@home项目贡献自己闲置的GPU计算力,协助抗击新冠状病毒疫情. 目前全球有超过40 ...

  3. 数据、人工智能和传感器按COVID-19新冠流感排列

    数据.人工智能和传感器按COVID-19新冠流感排列 Data, AI and sensors arrayed against COVID-19 各国政府.卫生保健专业人士和工业界争先恐后地应对Cov ...

  4. Python小白的数学建模课-B6. 新冠疫情 SEIR 改进模型

    传染病的数学模型是数学建模中的典型问题,常见的传染病模型有 SI.SIR.SIRS.SEIR 模型. SEIR 模型考虑存在易感者.暴露者.患病者和康复者四类人群,适用于具有潜伏期.治愈后获得终身免疫 ...

  5. SIR模型预测新冠病毒肺炎发病数据

    大家还好吗? 背景就不用多说了吧?本来我是初四上班的,现在延长到2月10日了.这是我工作以来时间最长的一个假期了.可惜哪也去不了.待在家里,没啥事,就用python模拟预测一下新冠病毒肺炎的数据吧.要 ...

  6. iMX287A基于嵌入式Qt的新冠肺炎疫情监控平台

    目录 1.前言 2.数据接口的获取 3.Qt界面的实现 4.在开发板上运行Qt程序 5.最终效果 6.代码下载 @ 1.前言 之前我使用在桌面版本Qt实现了肺炎疫情监控平台:基于Qt的新冠肺炎疫情数据 ...

  7. 面试刷题26:新冠攻击人类?什么攻击java平台?

    可恶的新冠病毒攻击人类,搞得IT就业形势相当不好?好在有钟南山院士带领我们提前开展好了防护工作! java作为基础平台安装在各种移动设备,PC,小型机,分布式服务器集群,各种不同的操作系统上.所以,对 ...

  8. Python模块---制作新冠疫情世界地图()

    目录 pyecharts模块 简介 安装pyecharts 测试pyecharts模块 pyecharts实战:绘制新冠肺炎疫情地图 需求分析 请求数据 提取数据 处理数据 制作可视化地图 设置可视化 ...

  9. python画新冠肺炎国内和世界各国累计确诊数量热图

    新冠肺炎国内疫情基本控制住,很多地方都开始摘下口罩了.但是国外的疫情依然处于爆发期,特别是美国,截止目前其累计确诊数量已突破110w.五一节北京柳絮杨絮满天飞,不适合外出.在家心血来潮,献丑画一下各地 ...

随机推荐

  1. 安装MySQL到Ubuntu 20.04

    本文的内容主要来自对How To Install MySQL on Ubuntu 20.04的翻译.在根据该文的指导下,我在自己的Ubuntu 20.04.3 LTS版本中安装了MySQL 8. St ...

  2. Cesium入门9 - Loading and Styling Entities - 加载和样式化实体

    Cesium入门9 - Loading and Styling Entities - 加载和样式化实体 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://c ...

  3. Ajax_Post用法

    Ajax_Post用法 post方法的用法其实跟get是大同小异的 唯一不同的地方就是我们需要修改server.js的文件 只需要将get修改为post即可 那么我为了方便操作我这里选择的是直接在下面 ...

  4. 【HarmonyOS】【JS】鸿蒙Js camera怎么拍照并使用image显示出来

    官网中有描述camera组件功能界面属性介绍,但是官网没有具体的demo让我们感受拍照的功能,今天写一篇demo来完善一下拍照的功能 demo 功能如下 第一步首先进行拍照功能 第二步 进行js页面跳 ...

  5. 集合框架-工具类-Collections-逆序替换

    1 package cn.itcast.p2.toolclass.collections.demo; 2 3 import java.util.ArrayList; 4 import java.uti ...

  6. Chrome DevTools 面板全攻略

    李华西,微医云服务团队前端开发工程师,喜欢瞎折腾,典型猫奴 Console 面板 此章节请打开 devtools/console/console.html 一起食用 一方面用来记录页面在执行过程中的信 ...

  7. ansible roles实践——安装httpd

    1. vim  httpd.yml 2.执行

  8. django之django-debug-toolbar调试工具配置与使用

    外部链接:https://blog.csdn.net/weixin_39198406/article/details/78821677 django-debug-toolbar的作用:进行性能调优,与 ...

  9. 2022.02.04 Day1

    前言 为日后的算法面试做准备,自己也很喜欢算法这个东西,每天3~5道题. 刷题 1.leetcode 209 长度最下的子数组 题目 长度最下的子数组 大致的意思是从数组中找到长度最小的数组,并且数组 ...

  10. APC 篇—— APC 执行

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...