经典的目标检测算法

目录

前言

一、基于区域的算法(Region-based Methods)

1. R-CNN(Regions with CNN features)

2. Fast R-CNN

3. Faster R-CNN

二、基于回归的算法(Regression-based Methods)

1. YOLO(You Only Look Once)

2. SSD(Single Shot MultiBox Detector)

三、应用场景


#目标检测

前言

经典的目标检测算法主要可以分为两类:基于区域的算法和基于回归的算法。这些算法在计算机视觉领域中扮演了非常重要的角色,特别是在如视频监控、自动驾驶、面部识别等应用中。

一、基于区域的算法(Region-based Methods)

基于区域的算法通过首先生成潜在的感兴趣区域(Regions of Interest, RoI),然后对这些区域进行分类和边界框回归。这类方法通常可以达到较高的准确率,但在速度上可能会受到影响。

1. R-CNN(Regions with CNN features)

  • 原理: R-CNN 通过使用选择性搜索算法生成约2000个候选区域,然后对每个区域使用CNN提取特征,最后通过支持向量机(SVM)进行分类和线性回归模型进行边框精修。
  • 优点: 可以在复杂背景中准确识别和定位目标。
  • 缺点: 需要为每个候选区域独立运行CNN,计算成本高,速度慢。

构建R-CNN网络的核心部分:

  1. 图像预处理和候选区域提取:使用OpenCV进行选择性搜索。
  2. 特征提取:使用预训练的CNN(如VGG16)。
  3. 分类器:使用支持向量机(SVM)对特征进行分类。
  4. 边界框回归器:调整候选区域的大小以更好地匹配目标。
import cv2
import torch
import torchvision.models as models
import torchvision.transforms as transforms
from sklearn import svm
from sklearn.externals import joblib
from sklearn.preprocessing import StandardScaler

# Step 1: Selective Search to propose regions
def selective_search(img):
    ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()
    ss.setBaseImage(img)
    ss.switchToSelectiveSearchFast()
    rects = ss.process()
    return rects[:2000]  # Limit to 2000 proposals

# Step 2: Feature extraction using a pre-trained CNN
def extract_features(image, rects, model, transform):
    features = []
    for x, y, w, h in rects:
        roi = image[y:y+h, x:x+w]
        roi_resized = cv2.resize(roi, (224, 224))  # Resize to fit CNN input
        tensor = transform(roi_resized)
        with torch.no_grad():
            feature = model(tensor.unsqueeze(0))  # Add batch dimension
        features.append(feature.flatten())
    return features

# Load a pre-trained VGG16 model
model_vgg16 = models.vgg16(pretrained=True).features
model_vgg16.eval()  # Set to evaluation mode

# Transformations for image preprocessing
transform = transforms.Compose([
    transforms.ToPILImage(),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# Step 3 and 4: Classifier and regressor setup (SVM in this case)
svm_classifier = svm.SVC()
scaler = StandardScaler()  # Feature scaling for SVM

# Dummy function for training and prediction (Example usage)
def train_and_predict(image_path):
    img = cv2.imread(image_path)
    rects = selective_search(img)
    features = extract_features(img, rects, model_vgg16, transform)
    features_scaled = scaler.fit_transform(features)  # Scale features
    svm_classifier.fit(features_scaled, labels)  # You need labels here for training
    predictions = svm_classifier.predict(features_scaled)
    return predictions, rects

# Example call (You need to provide the image path and labels)
# predictions, proposals = train_and_predict('path_to_image.jpg')
  • 这个代码提供了基本的R-CNN网络框架,但它需要调整和完善以适应特定任务,如正确处理标签和进行实际的模型训练。
  • 实际使用时,你还需要处理如何从数据集获取标签、训练支持向量机、以及如何精确地执行边界框回归等问题。

2. Fast R-CNN

  • 原理: Fast R-CNN 改进了 R-CNN,通过整个图像只运行一次CNN,并在特征图上使用RoI Pooling从每个候选区域生成固定大小的特征,再通过全连接层进行分类和边框回归。
  • 优点: 大大提高了训练和检测速度,同时简化了训练流程。
  • 缺点: 仍依赖于外部区域建议算法,如选择性搜索。

构建Fast R-CNN网络

我们将使用PyTorch中的预训练模型(如ResNet)作为我们的基础模型来提取特征,然后在其上构建ROI Pooling层和分类及回归层。

import torch
import torchvision
from torchvision.models.detection import fasterrcnn_resnet50_fpn
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.ops import RoIPool

# 设定设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 加载一个预训练的模型
model = torchvision.models.vgg16(pretrained=True).features.to(device)
model.eval()

# ROI Pooling 层,这里我们假设输出尺寸为7x7
roi_pooler = RoIPool(output_size=(7, 7), spatial_scale=1.0)

# 全连接层,这部分需要根据具体的类别数来定义
num_classes = 4  # 假设我们有3个类别加上背景
in_features = 512 * 7 * 7  # VGG16特征维度*池化后尺寸
classifier = torch.nn.Sequential(
    torch.nn.Linear(in_features, 4096),
    torch.nn.ReLU(),
    torch.nn.Dropout(),
    torch.nn.Linear(4096, 4096),
    torch.nn.ReLU(),
    torch.nn.Dropout(),
    torch.nn.Linear(4096, num_classes)
).to(device)

# 边界框回归器
bbox_regressor = torch.nn.Linear(4096, num_classes * 4).to(device)

def forward(images, proposals):
    with torch.no_grad():
        features = model(images)
    
    pooled_features = roi_pooler(features, proposals)
    pooled_features = pooled_features.view(pooled_features.size(0), -1)
    class_logits = classifier(pooled_features)
    bbox_regression = bbox_regressor(pooled_features)
    return class_logits, bbox_regression

# 假设我们已经有输入图像和提案
# images = torch.randn(1, 3, 800, 800).to(device)
# proposals = [torch.rand(1000, 4).to(device) * 800]  # 假设的提案

# output = forward(images, proposals)
# print(output)
  1. 预训练的模型:这里使用了VGG16作为特征提取层,你可以替换为任何其他的预训练模型。
  2. ROI Pooling:我们使用RoIPool层来从每个提议区域提取固定大小的特征。
  3. 分类和回归层:全连接层用于分类,另一个全连接层用于边界框回归。

3. Faster R-CNN

  • 原理: Faster R-CNN 在 Fast R-CNN 的基础上加入区域提议网络(Region Proposal Network, RPN),用于从特征图直接生成区域建议,实现了目标检测的端到端训练。
  • 优点: 几乎实时的检测速度,更高的准确率。
  • 缺点: 在处理非常小的目标时性能略有下降。

构建一个Faster R-CNN网络模型涉及更多的复杂性,因为它包括一个额外的组件:区域建议网络(Region Proposal Network, RPN),用于从特征图直接生成区域建议。PyTorch提供了一个较为简化的方式来使用和定制Faster R-CNN,包括使用预训练模型。我们将利用这些工具来构建并训练一个Faster R-CNN模型。

import torch
from torchvision.models.detection import fasterrcnn_resnet50_fpn
from torchvision.models.detection.rpn import AnchorGenerator
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor

# 加载预训练的Faster R-CNN模型
def create_faster_rcnn_model(num_classes):
    # 加载有预训练权重的Faster R-CNN模型
    model = fasterrcnn_resnet50_fpn(pretrained=True)

    # 获取分类器的输入特征数
    in_features = model.roi_heads.box_predictor.cls_score.in_features

    # 替换预训练的头部以新的头部(适用于新的类别数)
    model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)

    return model

# 设定设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 创建模型,这里示例中假定我们有4个类别(包括背景)
num_classes = 4
model = create_faster_rcnn_model(num_classes).to(device)

# 假设training_data_loader是一个可用的PyTorch DataLoader,提供训练图像和标注
def train_model(model, data_loader, num_epochs):
    model.train()
    optimizer = torch.optim.SGD(model.parameters(), lr=0.005, momentum=0.9, weight_decay=0.0005)

    for epoch in range(num_epochs):
        for images, targets in data_loader:
            images = list(image.to(device) for image in images)
            targets = [{k: v.to(device) for k, v in t.items()} for t in targets]

            loss_dict = model(images, targets)

            losses = sum(loss for loss in loss_dict.values())

            optimizer.zero_grad()
            losses.backward()
            optimizer.step()
        print(f"Epoch {epoch+1}, Loss: {losses.item()}")

# 调用训练函数,传入模型和数据加载器
# train_model(model, training_data_loader, num_epochs=10)
  1. 数据准备:你需要准备一个DataLoader,它输出的每个批次是一个图像列表和相应的目标字典列表,目标字典应包含boxes(边界框坐标)和labels(类别标签)。
  2. 模型训练:上述训练函数包含了基本的训练循环,这需要你有一个合适的数据加载器。
  3. 优化器参数:根据具体任务,可能需要调整学习率、动量等参数。

二、基于回归的算法(Regression-based Methods)

基于回归的算法将目标检测任务视为一个回归问题,直接预测图像中的目标类别和位置。

1. YOLO(You Only Look Once)

  • 原理: YOLO 将整个图像划分为网格,每个网格预测多个边界框和类别概率。这种设计使得YOLO可以在看到整个图像的情况下直接预测出目标的位置和类别。
  • 优点: 非常快速,适合实时应用。易于训练和直接优化。
  • 缺点: 对小对象的检测效果较差,且在边界框重叠的情况下准确度下降。

构建YOLO v3网络

YOLO v3使用了暗网(Darknet-53)作为其特征提取的基础网络。在这个例子中,我们将简化这个过程,使用预训练的模型来加快开发。我们将使用PyTorch提供的工具来自定义一个模型。

import torch
import torch.nn as nn
import torchvision.transforms as transforms
from torch.utils.data import DataLoader, Dataset
import numpy as np
import cv2
from PIL import Image

# 定义YOLO模型
class YOLOv3(nn.Module):
    def __init__(self, num_classes):
        super(YOLOv3, self).__init__()
        # 这里简化了网络结构,实际情况需要更多层和更复杂的结构
        self.backbone = nn.Sequential(
            nn.Conv2d(3, 16, 3, padding=1, stride=2),  # 简化版的暗网
            nn.BatchNorm2d(16),
            nn.LeakyReLU(0.1),
            nn.MaxPool2d(2, 2)
        )
        self.detector = nn.Sequential(
            nn.Conv2d(16, 32, 3, padding=1),
            nn.BatchNorm2d(32),
            nn.LeakyReLU(0.1),
            nn.Conv2d(32, (5 + num_classes) * 3, 1)  # 输出层
        )

    def forward(self, x):
        x = self.backbone(x)
        x = self.detector(x)
        return x

# 设定设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 创建模型实例,假设我们有20个类
model = YOLOv3(num_classes=20).to(device)

# 定义损失函数和优化器
class YoloLoss(nn.Module):
    def __init__(self):
        super(YoloLoss, self).__init__()

    def forward(self, predictions, targets):
        # 在这里添加实际的损失计算逻辑
        return torch.mean((predictions - targets) ** 2)

loss_fn = YoloLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 模拟一个简单的数据加载器
class DummyDataset(Dataset):
    def __getitem__(self, index):
        # 这里的数据生成只是示例,实际应用中需要加载和处理真实图像
        image = torch.randn(3, 416, 416)  # 假设输入尺寸是416x416
        label = torch.randn(13, 13, 3, 25)  # 假设我们的输出网格是13x13,每个单元格3个bbox
        return image, label

    def __len__(self):
        return 100

# 数据加载器
dataset = DummyDataset()
data_loader = DataLoader(dataset, batch_size=10, shuffle=True)

# 训练循环
def train(model, data_loader):
    model.train()
    for epoch in range(5):  # 训练5个epoch
        for images, targets in data_loader:
            images, targets = images.to(device), targets.to(device)
            optimizer.zero_grad()
            outputs = model(images)
            loss = loss_fn(outputs, targets)
            loss.backward()
            optimizer.step()
        print(f"Epoch {epoch+1}, Loss: {loss.item()}")

# 开始训练
train(model, data_loader)
  • 这个示例极大地简化了YOLO的实现,真实的YOLO网络需要更多的层和更复杂的结构,包括多尺度输出。
  • YOLO的损失函数相对复杂,因为它需要同时考虑坐标预测、置信度和类别预测。这里使用的是简单的平方损失作为例子。
  • 实际使用时,你应该利用标准数据集进行训练,并严格按照原始论文或其他可靠资源实现详细的网络架构和损失函数。

2. SSD(Single Shot MultiBox Detector)

  • 原理: SSD 同时使用多个特征图预测不同尺寸的目标,每个特征图的每个位置都会预测多个默认框和对应的类别概率。
  • 优点: 在多种尺寸的目标检测上表现良好,检测速度快。
  • 缺点: 在极小或者极大的对象上的表现可能不如专门针对该尺寸设计的网络。

构建SSD网络

以下是构建SSD网络的基本步骤,包括定义网络结构、损失函数和一个简单的训练循环。

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision.models import vgg16
from torchvision.ops import MultiScaleRoIAlign, boxes as box_ops

# 定义SSD模型
class SSD(nn.Module):
    def __init__(self, num_classes):
        super(SSD, self).__init__()
        self.num_classes = num_classes
        self.backbone = vgg16(pretrained=True).features
        
        # 额外的特征层,用于检测
        self.additional_layers = nn.ModuleList([
            nn.Sequential(nn.Conv2d(512, 1024, kernel_size=3, padding=1), nn.ReLU()),
            nn.Sequential(nn.Conv2d(1024, 1024, kernel_size=1), nn.ReLU()),
            nn.Sequential(nn.Conv2d(1024, 256, kernel_size=1), nn.ReLU(),
                          nn.Conv2d(256, 512, kernel_size=3, stride=2, padding=1), nn.ReLU())
        ])
        
        # 定位和置信度头
        self.loc_head = nn.ModuleList([
            nn.Conv2d(512, 4 * 4, kernel_size=3, padding=1),
            nn.Conv2d(1024, 6 * 4, kernel_size=3, padding=1),
            nn.Conv2d(512, 6 * 4, kernel_size=3, padding=1)
        ])
        
        self.conf_head = nn.ModuleList([
            nn.Conv2d(512, 4 * num_classes, kernel_size=3, padding=1),
            nn.Conv2d(1024, 6 * num_classes, kernel_size=3, padding=1),
            nn.Conv2d(512, 6 * num_classes, kernel_size=3, padding=1)
        ])

    def forward(self, x):
        features = []
        for i in range(23):
            x = self.backbone[i](x)
        features.append(x)
        
        for layer in self.additional_layers:
            x = layer(x)
            features.append(x)
        
        loc_preds = []
        conf_preds = []
        for feature, loc_head, conf_head in zip(features, self.loc_head, self.conf_head):
            loc_preds.append(loc_head(feature).permute(0, 2, 3, 1).contiguous().view(x.size(0), -1, 4))
            conf_preds.append(conf_head(feature).permute(0, 2, 3, 1).contiguous().view(x.size(0), -1, self.num_classes))
        
        loc_preds = torch.cat(loc_preds, 1)
        conf_preds = torch.cat(conf_preds, 1)
        
        return loc_preds, conf_preds

# 定义损失函数
class SSDLoss(nn.Module):
    def __init__(self):
        super(SSDLoss, self).__init__()
    
    def forward(self, loc_preds, loc_targets, conf_preds, conf_targets):
        # 计算位置损失
        pos = conf_targets > 0  # 置信度大于0的为正样本
        num_pos = pos.sum(dim=1, keepdim=True)
        pos_loc_preds = loc_preds[pos]
        pos_loc_targets = loc_targets[pos]
        loc_loss = F.smooth_l1_loss(pos_loc_preds, pos_loc_targets, reduction='sum') / num_pos.sum()
        
        # 计算置信度损失
        conf_loss = F.cross_entropy(conf_preds.view(-1, self.num_classes), conf_targets.view(-1), reduction='none')
        conf_loss = conf_loss.view_as(conf_targets)
        neg = conf_targets == 0  # 背景
        pos_neg = torch.cat([pos, neg], 1)
        loss_c = conf_loss * pos_neg
        conf_loss = loss_c.sum() / num_pos.sum()
        
        return loc_loss + conf_loss

# 实例化模型和损失函数
model = SSD(num_classes=21).to(device)  # COCO数据集类别数 + 1背景
loss_fn = SSDLoss().to(device)

训练准备

实际训练前,你需要准备好数据加载器,定义优化器等。然后,你可以按照下面的框架进行训练:

# 假设data_loader是你的数据加载器
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

for epoch in range(num_epochs):
    model.train()
    for images, targets in data_loader:
        images = images.to(device)
        loc_targets, conf_targets = [t['boxes'].to(device), t['labels'].to(device) for t in targets]

        optimizer.zero_grad()
        loc_preds, conf_preds = model(images)
        loss = loss_fn(loc_preds, loc_targets, conf_preds, conf_targets)
        loss.backward()
        optimizer.step()
    print(f"Epoch {epoch}: Loss {loss.item()}")

这段代码为SSD的基本实现提供了框架,但细节实现如数据预处理、性能优化和参数调整需要根据具体任务细致调整。

三、应用场景

  • 基于区域的算法: 通常用于需要高精度检测的场景,如自动驾驶车辆的行人和车辆检测,医疗图像分析等。

  • 基于回归的算法: 适用于需要快速响应的应用,例如视频监控实时分析,移动和嵌入式视觉系统等。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLO新鲜腐烂水果检测数据集:8类,11000多张图像,标注完整

YOLO新鲜腐烂水果检测数据集:8类,11000多张图像,yolo标注完整,包含烂苹果,烂香蕉,烂橙子,烂石榴,好苹果,好香蕉,好橙子,好石榴8个类别 图像统一分…

仿真软件搭建注意事项

搭建仿真软件是一个复杂的过程,涉及到软件工程、计算数学、工程学、物理学以及产品设计等多个学科的融合。以下是搭建仿真软件的注意事项: 需求分析:明确仿真软件的目标和功能需求,包括仿真的对象、仿真的精度、所需的物理模型等…

三招教你成为朋友圈运营高手,赶紧get起来!

朋友圈作为一个重要的营销推广渠道,是能够为我们带来很多收益的。今天就给大家分享朋友圈运营的三个技巧,快快Get起来吧! 第一招:明确人设定位 要在朋友圈里脱颖而出,首先我们需要明确自己的人设定位。选择一个与自己…

【Chapter3】中断与处理机调度,计算机操作系统教程,第四版,左万利,王英

文章目录 一、中断与中断系统1.1 什么是中断?1.1.1 外中断(硬件)1.1.2 异常(内中断) 1.2 中断机制的原理1.2.1 中断装置1、中断源与中断字2、中断类型与中断向量3、中断嵌套与系统栈4、中断优先级别与中断屏蔽 1.2.2 中…

【热门话题】AI作画算法原理解析

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 AI作画算法原理解析AI作画算法概述基础原理:机器学习与深度学习卷积…

基于Springboot的人职匹配推荐系统

基于SpringbootVue的人职匹配推荐系统的设计与实现 开发语言:Java数据库:MySQL技术:SpringbootMybatis工具:IDEA、Maven、Navicat 系统展示 用户登录 首页 企业信息 岗位信息 新闻资讯 后台管理 用户管理 企业信息管理 岗位信…

docker系列7:docker安装ES

目录 传送门 Docker安装ES 确定版本 拉取镜像 执行拉取ES镜像 查看ES镜像 运行ES 创建一个新的docker网络 启动一个Elasticsearch容器 查看运行结果 ES启动内存不足 访问ES 公网访问 传送门 docker系列1:docker安装 docker系列2:阿里云镜…

这个禁止打字,只能发语音的AI Native产品,成了硅谷最火的社交软件

最近,一款AI驱动的社交应用AirChat在硅谷引发了热切关注,这款产品背后的AI技术可以实时将语音转录为文字,并支持多语言翻译。综合来看,AirChat的火可以持续多久呢? 过去一周,硅谷线上到处充斥着求链接的声音…

学习Django

1.python安装是会有几个主要目录: 2.如果某个路径加入了环境变量,那么在命令行直接输入他下面的文件就能找到,不用输入完整路径 2.过程 (1)安装 (2)建项目 在终端: (…

抖音 小程序 获取手机号 报错 getPhoneNumber:fail auth deny

这是因为 当前小程序没有获取 手机号的 权限 此能力仅支持小程序通过试运营期后可用,默认获取权限,无需申请; https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/guide/open-capabilities/acquire-phone-number-acqu…

vbox两步解决VirtualBox共享文件夹在Windows下的符号链接创建问题

默认情况下,VirtualBox 的共享文件夹特性在 Windows 下工作是有问题的,如果你运行一些需要符号连接(Symlink)的程序,比如默认设置的 yarn 或者 npm,由于 npm 包在安装之后会在 ./node_modules/.bin 创建在 …

11、【桥接模式】让将抽象和实现分离,使得它们可以独立地变化

你好,我是程序员雪球。 今天我们来聊聊 23 种设计模式中,一种常见的结构型模式,桥接模式。聊聊它的设计思想、应用场景,以及如何使用。 一、设计思想 桥接模式(Bridge Pattern)是一种结构型设计模式&#…

C++ 之二叉搜索树

目录 学习目标: 1.二叉搜索树 1.1二叉搜索树的概念 1.2二叉搜索树的操作 1.二叉搜索树的查找 2.二叉树的插入 3.二叉树的删除* 2.二叉搜索树的实现 3.二叉树性能分析 1.二叉搜索树 1.1二叉搜索树的概念 二叉搜索树又称二叉排序树,它或者是一棵…

spring的bean创建流程源码解析

文章目录 IOC 和 DIBeanFactoryApplicationContext实现的接口1、BeanFactory接口2、MessageSource 国际化接口3、ResourcePatternResolver,资源解析接口4、EnvironmentCapable接口,用于获取环境变量,配置信息5、ApplicationEventPublisher 事…

Java文件流练习

1 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件 import java.io.File; import java.util.Scanner;public class Main {public static void main(String[] args) {Scanne…

Windows 10 安装配置WSL2(Ubuntu 20.04)教程

Windows 10 安装配置WSL2(Ubuntu 20.04)教程 一、WSL简介 WSL(Windows Subsystem for Linux)是一个兼容层,允许在Windows 10上原生运行Linux二进制可执行文件。 二、安装WSL2 3.1 传统手动安装 更新系统&#xff…

技术速递|Java on Azure Tooling 3月更新 - Java on Azure 开发工具未来六个月路线图发布

作者:Jialuo Gan - Program Manager, Developer Division At Microsoft 排版:Alan Wang 大家好,欢迎阅读 Java on Azure 工具的三月更新。在本次更新中,我们将分享未来几个月对 Java on Azure 开发工具的投资。此外,我…

无限多交换机串联,可以将网线无限延长吗?

网线使用时为了网络质量一般不超过100m,那我每隔100m接一个交换机是不是就可以无限延长了? 完全没有问题。 但是慎用无限、永远、永恒这些字眼,“爱你到永远”这句山盟海誓,看看现在的离婚率就知道有多么不靠谱。 但是&#xff…

MySQL数据库精讲001——概述

MySQL数据库精讲001——概述 文章目录 MySQL数据库精讲001——概述1.1 安装1.1.1 版本1.1.2 安装一、下载二、解压三、配置1. 添加环境变量2. 初始化MySQL3. 注册MySQL服务4. 启动MySQL服务5. 修改默认账户密码 四、登录MySQL五、卸载MySQL 1.1.3 连接1.1.4 企业使用方式(了解)…

共享单车(二):项目日志

stdin, stdout, stderr Linux系统下,当一个用户进程被创建时,与之对应的三个数据流(stdin,stdout和stderr,即三个文件)也会被创建。 stdin,标准输入文件,通常对应着终端的键盘。 s…
最新文章