365天深度学习训练营-第P2周:彩色图片识别

news2024/12/23 0:29:45

目录

一、前言

二、我的环境

三、代码实现

1、数据下载以及可视化

2、CNN模型

3、训练结果可视化

 4、随机图像预测

 四、模型优化

1、CNN模型

2、VGG-16模型

3、Alexnet模型

4、Resnet模型


一、前言

>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/xLjALoOD8HPZcH563En8bQ) 中的学习记录博客**
>- **🍦 参考文章:365天深度学习训练营-第P2周:彩色图片识别(训练营内部成员可读)**
>- **🍖 原作者:[K同学啊|接辅导、项目定制](https://mtyjkh.blog.csdn.net/)**
● 难度:夯实基础⭐⭐
● 语言:Python3、Pytorch3
● 时间:11月26日-12月2日
🍺 要求:
1. 自己搭建CNN网络框架
2. 调用官方的VGG-16网络框架
 
🍻 拔高(可选):
1. 验证集准确率达到85%
2. 使用PPT画出VGG-16算法框架图
 

二、我的环境

语言环境:Python3.7

编译器:jupyter notebook

深度学习环境:TensorFlow2

三、代码实现

# 设置GPU
import copy

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from torchvision import datasets, transforms, models
import torchvision
import random

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

device

# 导入数据
train_ds = torchvision.datasets.CIFAR10('data',
                                        train=True,
                                        transform=torchvision.transforms.ToTensor(),  # 将数据类型转化为Tensor
                                        download=True)

test_ds = torchvision.datasets.CIFAR10('data',
                                       train=False,
                                       transform=torchvision.transforms.ToTensor(),  # 将数据类型转化为Tensor
                                       download=True)
batch_size = 32

train_dl = torch.utils.data.DataLoader(train_ds,
                                       batch_size=batch_size,
                                       shuffle=True)

test_dl = torch.utils.data.DataLoader(test_ds,
                                      batch_size=batch_size)
# 取一个批次查看数据格式
# 数据的shape为:[batch_size, channel, height, weight]
# 其中batch_size为自己设定,channel,height和weight分别是图片的通道数,高度和宽度。
imgs, labels = next(iter(train_dl))
imgs.shape
import numpy as np

# 指定图片大小,图像大小为20宽、5高的绘图(单位为英寸inch)
plt.figure(figsize=(20, 5))
for i, imgs in enumerate(imgs[:20]):
    # 维度缩减
    npimg = imgs.numpy().transpose((1, 2, 0))
    # 将整个figure分成2行10列,绘制第i+1个子图。
    plt.subplot(2, 10, i + 1)
    plt.imshow(npimg, cmap=plt.cm.binary)
    plt.axis('off')
# 构建CNN网络
import torch.nn.functional as F

num_classes = 10  # 图片的类别数


class Model(nn.Module):
    def __init__(self):
        super().__init__()
        # 特征提取网络
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3)  # 第一层卷积,卷积核大小为3*3
        self.pool1 = nn.MaxPool2d(kernel_size=2)  # 设置池化层,池化核大小为2*2
        self.conv2 = nn.Conv2d(64, 64, kernel_size=3)  # 第二层卷积,卷积核大小为3*3
        self.pool2 = nn.MaxPool2d(kernel_size=2)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3)  # 第二层卷积,卷积核大小为3*3
        self.pool3 = nn.MaxPool2d(kernel_size=2)

        # 分类网络
        self.fc1 = nn.Linear(512, 256)
        self.fc2 = nn.Linear(256, num_classes)

    # 前向传播
    def forward(self, x):
        x = self.pool1(F.relu(self.conv1(x)))
        x = self.pool2(F.relu(self.conv2(x)))
        x = self.pool3(F.relu(self.conv3(x)))

        x = torch.flatten(x, start_dim=1)

        x = F.relu(self.fc1(x))
        x = self.fc2(x)

        return x


from torchinfo import summary

# 将模型转移到GPU中(我们模型运行均在GPU中进行)
model = Model().to(device)

summary(model)
# 设置超参数
loss_fn = nn.CrossEntropyLoss()  # 创建损失函数
learn_rate = 1e-2  # 学习率
opt = torch.optim.SGD(model.parameters(), lr=learn_rate)


# 编写训练函数
# 训练循环
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)  # 训练集的大小,一共60000张图片
    num_batches = len(dataloader)  # 批次数目,1875(60000/32)

    train_loss, train_acc = 0, 0  # 初始化训练损失和正确率

    for X, y in dataloader:  # 获取图片及其标签
        X, y = X.to(device), y.to(device)

        # 计算预测误差
        pred = model(X)  # 网络输出
        loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失

        # 反向传播
        optimizer.zero_grad()  # grad属性归零
        loss.backward()  # 反向传播
        optimizer.step()  # 每一步自动更新

        # 记录acc与loss
        train_acc += (pred.argmax(1) == y).type(torch.float).sum().item()
        train_loss += loss.item()

    train_acc /= size
    train_loss /= num_batches

    return train_acc, train_loss


# 编写测试函数
def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)  # 测试集的大小,一共10000张图片
    num_batches = len(dataloader)  # 批次数目,313(10000/32=312.5,向上取整)
    test_loss, test_acc = 0, 0

    # 当不进行训练时,停止梯度更新,节省计算内存消耗
    with torch.no_grad():
        for imgs, target in dataloader:
            imgs, target = imgs.to(device), target.to(device)

            # 计算loss
            target_pred = model(imgs)
            loss = loss_fn(target_pred, target)

            test_loss += loss.item()
            test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()

    test_acc /= size
    test_loss /= num_batches

    return test_acc, test_loss


epochs = 10
train_loss = []
train_acc = []
test_loss = []
test_acc = []

for epoch in range(epochs):
    model.train()
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)

    model.eval()
    epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)
    # 保存最优模型
    if epoch_test_acc > best_acc:
        best_acc = epoch_test_acc
        best_model = copy.deepcopy(model)

    train_acc.append(epoch_train_acc)
    train_loss.append(epoch_train_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)

    template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')
    print(template.format(epoch + 1, epoch_train_acc * 100, epoch_train_loss, epoch_test_acc * 100, epoch_test_loss))

PATH = './best_model.pth '
torch.save(model.state_dict(), PATH)
print('Done')

# 训练结果
import matplotlib.pyplot as plt
# 隐藏警告
import warnings

warnings.filterwarnings("ignore")  # 忽略警告信息
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.rcParams['figure.dpi'] = 100  # 分辨率

epochs_range = range(epochs)

plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)

plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

plt.figure(figsize=(16, 14))
for i in range(10):
    img_data, label_id = random.choice(list(zip(test_ds.data, test_ds.targets)))
    img = transforms.ToPILImage()(img_data)
    predict_id = torch.argmax(model(transform(img).to(device).unsqueeze(0)))
    predict = test_ds.classes[predict_id]
    label = test_ds.classes[label_id]
    plt.subplot(3, 4, i + 1)
    plt.imshow(img)
    plt.title(f'truth:{label}\npredict:{predict}')

1、数据下载以及可视化

 

2、CNN模型

 

3、训练结果可视化

得到的训练集和测试集的的acc和loss数据可视化,得知预测的结果并不是很满意,所以本文后面会对模型进行改善。

 4、随机图像预测

 四、模型优化

1、CNN模型

主要的思路就是增加卷积层和池化层 可以在其中加BN层

BN的本质原理:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理(归一化至:均值0、方差为1),然后再进入网络的下一层。不过文献归一化层,可不像我们想象的那么简单,它是一个可学习、有参数(γ、β)的网络层。

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Sequential(
            nn.Conv2d(3, 12, kernel_size=5, padding=0),  # 12*220*220
            nn.BatchNorm2d(12),
            nn.ReLU()
        )
        self.conv2 = nn.Sequential(
            nn.Conv2d(12, 12, kernel_size=5, padding=0),  # 12*216*216
            nn.BatchNorm2d(12),
            nn.ReLU()
        )
        self.pool3 = nn.Sequential(
            nn.MaxPool2d(2),  # 12*108*108
            nn.Dropout(0.15)
        )
        self.conv4 = nn.Sequential(
            nn.Conv2d(12, 24, kernel_size=5, padding=0),  # 24*104*104
            nn.BatchNorm2d(24),
            nn.ReLU()
        )
        self.conv5 = nn.Sequential(
            nn.Conv2d(24, 24, kernel_size=5, padding=0),  # 24*100*100
            nn.BatchNorm2d(24),
            nn.ReLU()
        )
        self.pool6 = nn.Sequential(
            nn.MaxPool2d(2),  # 24*50*50
            nn.Dropout(0.15)
        )
        self.fc = nn.Sequential(
            nn.Linear(24 * 50 * 50, num_classes)
        )

    def forward(self, x):
        batch_size = x.size(0)
        x = self.conv1(x)  # 卷积-BN-激活
        x = self.conv2(x)  # 卷积-BN-激活
        x = self.pool3(x)  # 池化-Drop
        x = self.conv4(x)  # 卷积-BN-激活
        x = self.conv5(x)  # 卷积-BN-激活
        x = self.pool6(x)  # 池化-Drop
        x = x.view(batch_size, -1)  # flatten 变成全连接网络需要的输入 (batch, 24*50*50) ==> (batch, -1), -1 此处自动算出的是21168
        x = self.fc(x)

        return x

 模型结构图可以在进行绘制

NN SVG (alexlenail.me)

2、VGG-16模型

class Vgg16_net(nn.Module):
    def __init__(self):
        super(Vgg16_net, self).__init__()

        self.layer1 = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=1, padding=1),  # (32-3+2)/1+1=32   32*32*64
            nn.BatchNorm2d(64),
            # inplace-选择是否进行覆盖运算
            # 意思是是否将计算得到的值覆盖之前的值,比如
            nn.ReLU(inplace=True),
            # 意思就是对从上层网络Conv2d中传递下来的tensor直接进行修改,
            # 这样能够节省运算内存,不用多存储其他变量

            nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, stride=1, padding=1),
            # (32-3+2)/1+1=32    32*32*64
            # Batch Normalization强行将数据拉回到均值为0,方差为1的正太分布上,
            # 一方面使得数据分布一致,另一方面避免梯度消失。
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),

            nn.MaxPool2d(kernel_size=2, stride=2)  # (32-2)/2+1=16         16*16*64
        )

        self.layer2 = nn.Sequential(
            nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1),
            # (16-3+2)/1+1=16  16*16*128
            nn.BatchNorm2d(128),
            nn.ReLU(inplace=True),

            nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, stride=1, padding=1),
            # (16-3+2)/1+1=16   16*16*128
            nn.BatchNorm2d(128),
            nn.ReLU(inplace=True),

            nn.MaxPool2d(2, 2)  # (16-2)/2+1=8     8*8*128
        )

        self.layer3 = nn.Sequential(
            nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, stride=1, padding=1),  # (8-3+2)/1+1=8   8*8*256
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),

            nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1),  # (8-3+2)/1+1=8   8*8*256
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),

            nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, stride=1, padding=1),  # (8-3+2)/1+1=8   8*8*256
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),

            nn.MaxPool2d(2, 2)  # (8-2)/2+1=4      4*4*256
        )

        self.layer4 = nn.Sequential(
            nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, stride=1, padding=1),
            # (4-3+2)/1+1=4    4*4*512
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),

            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1),
            # (4-3+2)/1+1=4    4*4*512
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),

            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1),
            # (4-3+2)/1+1=4    4*4*512
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),

            nn.MaxPool2d(2, 2)  # (4-2)/2+1=2     2*2*512
        )

        self.layer5 = nn.Sequential(
            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1),
            # (2-3+2)/1+1=2    2*2*512
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),

            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1),
            # (2-3+2)/1+1=2     2*2*512
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),

            nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, stride=1, padding=1),
            # (2-3+2)/1+1=2      2*2*512
            nn.BatchNorm2d(512),
            nn.ReLU(inplace=True),

            nn.MaxPool2d(2, 2)  # (2-2)/2+1=1      1*1*512
        )

        self.conv = nn.Sequential(
            self.layer1,
            self.layer2,
            self.layer3,
            self.layer4,
            self.layer5
        )

        self.fc = nn.Sequential(
            # y=xA^T+b  x是输入,A是权值,b是偏执,y是输出
            # nn.Liner(in_features,out_features,bias)
            # in_features:输入x的列数  输入数据:[batchsize,in_features]
            # out_freatures:线性变换后输出的y的列数,输出数据的大小是:[batchsize,out_features]
            # bias: bool  默认为True
            # 线性变换不改变输入矩阵x的行数,仅改变列数
            nn.Linear(512, 512),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),

            nn.Linear(512, 256),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),

            nn.Linear(256, 10)
        )

    def forward(self, x):
        x = self.conv(x)
        # 这里-1表示一个不确定的数,就是你如果不确定你想要reshape成几行,但是你很肯定要reshape成512列
        # 那不确定的地方就可以写成-1

        # 如果出现x.size(0)表示的是batchsize的值
        # x=x.view(x.size(0),-1)
        x = x.view(-1, 512)
        x = self.fc(x)
        return x

模型结构图大致如下

3、Alexnet模型

可以使用 torchvision.models定义神经网络

# 使用torchvision.models定义神经网络
net_a = models.alexnet(num_classes = 10)
print(net_a)

# 定义loss函数:
loss_fn = nn.CrossEntropyLoss()
print(loss_fn)

# 定义优化器
net = net_a

Learning_rate = 0.01  # 学习率

# optimizer = SGD: 基本梯度下降法
# parameters:指明要优化的参数列表
# lr:指明学习率
# optimizer = torch.optim.Adam(model.parameters(), lr = Learning_rate)
optimizer = torch.optim.SGD(net.parameters(), lr=Learning_rate, momentum=0.9)
print(optimizer)

 

 

 模型结构图

4、Resnet模型

class ResidualBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride = 1, shotcut = None):
        super(ResidualBlock, self).__init__()
        self.conv1 = conv3x3(in_channels, out_channels,stride)
        self.bn1 = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)

        self.conv2 = conv3x3(out_channels, out_channels)
        self.bn2 = nn.BatchNorm2d(out_channels)
        self.shotcut = shotcut

    def forward(self, x):
        residual = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn2(out)
        if self.shotcut:
            residual = self.shotcut(x)
        out += residual
        out = self.relu(out)
        return out
class ResNet(nn.Module):
    def __init__(self, block, layer, num_classes = 10):
        super(ResNet, self).__init__()
        self.in_channels = 16
        self.conv = conv3x3(3,16)
        self.bn = nn.BatchNorm2d(16)
        self.relu = nn.ReLU(inplace=True)

        self.layer1 = self.make_layer(block, 16, layer[0])
        self.layer2 = self.make_layer(block, 32, layer[1], 2)
        self.layer3 = self.make_layer(block, 64, layer[2], 2)
        self.avg_pool = nn.AvgPool2d(8)
        self.fc = nn.Linear(64, num_classes)

    def make_layer(self, block, out_channels, blocks, stride = 1):
        shotcut = None
        if(stride != 1) or (self.in_channels != out_channels):
            shotcut = nn.Sequential(
                nn.Conv2d(self.in_channels, out_channels,kernel_size=3,stride = stride,padding=1),
                nn.BatchNorm2d(out_channels))

        layers = []
        layers.append(block(self.in_channels, out_channels, stride, shotcut))

        for i in range(1, blocks):
            layers.append(block(out_channels, out_channels))
            self.in_channels = out_channels
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.avg_pool(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x

模型图转自知乎

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/51466.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022年钒电池行业研究报告

第一章 行业概况 钒电池(Vanadium Redox Battery,缩写为VRB),全称为全钒氧化还原液流电池,是一种活性物质呈循环流动液态的氧化还原电池。钒电池可以作为大容量储能电站的电池,其工作原理如下:…

Unity 2021 请求 Android 12 读取本地文件权限

目标 工具: Unity 2021.2.14c1f1Android 12 系统手机 目标:实现Unity打出来的Apk包能请求读写android手机本地文件权限 原理 在Android系统中,操作手机中不安全的数据时,需要配置相应的权限,只有经过用户许可才能…

[附源码]JAVA毕业设计个人信息管理系统(系统+LW)

[附源码]JAVA毕业设计个人信息管理系统(系统LW) 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术…

深度学习-第三章概率与信息论

前言 概率论学科定义概率与信息论在人工智能领域的应用 3.1,为什么要使用概率论3.2,随机变量3.3,概率分布 3.3.1,离散型变量和概率质量函数3.3.2,连续型变量和概率密度分布函数 3.4,边缘概率3.5&#xff0c…

量子计算新突破!来源于150年前的思想实验

澳大利亚新南威尔士大学的研究表明,使用现代版本的“麦克斯韦妖”,可将量子比特重置为“0”态的错误减少了20倍。 Andrea Morello教授解释了麦克斯韦妖思想实验如何与他的团队通过仅选择冷电子进行量子计算的成就相类比。(图片来源&#xff1…

Go-Windows环境的快速搭建

下载 Downloads - The Go Programming Language 或者直接到指定版本下载可以根据个人喜好,下载zip或者执行版 下载后文件夹 查看版本 必须查看版本,通过go version命令进行查看最新版本1.19.3版本 配置的GoPath 已经自动配置进去 需要重新进入一个新的…

HBuilder X 导入git项目以及拉取和推送

1. 首先在 HB中 > 工具 > 插件安装 > Git插件 2. 安装好 Git 插件之后还要安装一个 tortoisegit (小乌龟) tortoisegit : 这里根据电脑下载对应的位数,需要转换成中文的可以下载中文包: 安装 tortoisegit : 1. 双击刚刚下载的msi文件进入安装 2. 连续两次next之后…

[附源码]计算机毕业设计JAVA校园环境保护监督系统

[附源码]计算机毕业设计JAVA校园环境保护监督系统 项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM my…

虚拟机NAL模式连接linux系统

windows虚拟机连外网,相当于设置双网卡,虚拟机编辑网关如下: 在window系统查看设置vmnet8 在linux系统配置ip静态网址 cd /etc/sysconfig/network-scripts/ vim ifcfg-ens33在linux上重启网卡。 在window上添加路由,先查询路由&a…

C语言经典题目之字符串逆序

目录 一、字符串逆序(基础题) 1.一个经典的错误,标准的零分 2.采用gets函数来修补漏洞 ​编辑 3.非要使用scanf怎么办? 4.使用指针来实现逆序函数 5.将函数修改为,只要传入两个地址,就能逆序这两个地址…

最新 | VDA-ISA5.0.4最新版本发布,汽车企业如何增强信息安全?

汽车行业拥有广泛而复杂的供应链,包括汽车整车制造商、不同层级的零部件厂商、供应商、服务商等众多企业。在这个链条上,其中任何一家企业的网络安全问题不论是数据泄密还是内外部攻击都有可能对整个供应链造成巨大影响。 比如2021年6月,某德…

Apifox很难不爱

一、背景 项目开发我们都知道在一个项目团队中是由很多角色组成,最常见团队的就是前端开发工程师、客户端开发工程师、服务端开发工程师组成一个团队,团队之间进行合作,一般我们都离不开API接口管理和测试,API接口管理可以理解为前…

推荐,文本转图像,图像转图像运营再也不用担心配图了

由 CompVis 领导的 Stable Diffusion V1 改变了开源人工智能模型的性质,并在全球范围内催生了数百个其他模型和创新。Stable Diffusion 如今也是所有软件中最快攀升至 Github 10K Stars 的软件之一,在不到两个月的时间里,它的 Stars 飙升至 3…

【内网安全】——windows信息收集

作者名:Demo不是emo 主页面链接:主页传送门 创作初心:舞台再大,你不上台,永远是观众,没人会关心你努不努力,摔的痛不痛,他们只会看你最后站在什么位置,然后羡慕或鄙夷座…

Nginx安装

目录 1. 安装必要环境 1.1 需要安装gcc环境 1.2 PERE 1.3 zlib 1.4 openssl 2. 安装nginx 2.1 下载和解压 2.2 编译 2.2.1 设定配置 2.2.2 编译 2.2.3 安装 3. 启动nginx 4. 配置环境变量 5. 加入system管理 1. 下载Nginx 1. 安装必要环境 1.1 需要安装gcc环境 y…

基于PHP+MySQL学院信息发布系统的设计与实现

再添加完最新动态后可以点击最新动态管理,对已经添加过的最新动态进行编辑和删除,绑定的主要信息包括用文章标题,发布人,发布时间,文章类型,内容等信息 信息技术学院信息发布系统,是一个为学校提供信息的平台,是完全的,高速的,开放的,其核心思想是提供一个以自然语言为主的用户…

算法竞赛入门【码蹄集进阶塔335题】(MT2276-2280)

算法竞赛入门【码蹄集进阶塔335题】(MT2276-2280) 文章目录算法竞赛入门【码蹄集进阶塔335题】(MT2276-2280)前言为什么突然想学算法了?为什么选择码蹄集作为刷题软件?目录1. MT2276 数的自我2. MT2277 分数个数3. MT2278 欧拉函数…

[附源码]Python计算机毕业设计Django房屋租赁系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

Web3 来了,让我们展开双手拥抱它吧!

Web3的由来 在介绍Web3概念,有必要阐述下当下的网络世界。而如今的互联网正处于Web2阶段,其已经帮助数以亿计的人融入这个互联网大家庭,可在网络上构建可靠、稳定的基础设施。然而也正是Web2中心化网络成就了极少数互联网巨头,他…

基于STM32的智能家居控制系统设计与实现(带红外遥控控制空调)

1. 前言 智能家居作为家庭信息化的实现方式,已经成为社会信息化发展的重要组成部分,物联网因其巨大的应用前景,将是智能家居产业发展过程中一个比较现实的突破口,对智能家居的产业发展具有重大意义。 本文基于现有智能家居技术设计和实现情况,本着方便操作、增强功能、贴…