PyTorch訓練關鍵點

1.背景

????????在網上找了一些資料用來訓練關鍵點,一般都是人臉或者車牌關鍵點訓練,或者是聯合檢測一起訓練。很少有是單獨基于輕量級網絡訓練單獨關鍵點模型的工程,本文簡單介紹一種簡單方法和代碼。

2.代碼模塊

(1)網絡結構

文件:model.py

import torch.nn as nn
import torch
import torch.nn.functional as F
import torch.nn.init as init

class Fire(nn.Module):

? ? def __init__(self, inplanes, squeeze_planes,
? ? ? ? ? ? ? ? ?expand1x1_planes, expand3x3_planes):
? ? ? ? super(Fire, self).__init__()
? ? ? ? self.inplanes = inplanes
? ? ? ? self.squeeze = nn.Conv2d(inplanes, squeeze_planes, kernel_size=1)
? ? ? ??
? ? ? ? self.squeeze_activation = nn.ReLU(inplace=True)
? ? ? ??
? ? ? ? self.expand1x1 = nn.Conv2d(squeeze_planes, expand1x1_planes,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?kernel_size=1)
? ? ? ? #self.expand1x1_activation = nn.ReLU(inplace=True)
? ? ? ? self.expand3x3 = nn.Conv2d(squeeze_planes, expand3x3_planes,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?kernel_size=3, padding=1)
? ? ? ? #self.expand3x3_activation = nn.ReLU(inplace=True)

? ? def forward(self, x):
? ? ? ? x = self.squeeze_activation(self.squeeze(x))
? ? ? ? return torch.cat([
? ? ? ? ? ? self.expand1x1(x),
? ? ? ? ? ? self.expand3x3(x)
? ? ? ? ], 1)

class RegressNet(nn.Module): ??
? ? def __init__(self,version=1.0,export=False):
? ? ? ? super(RegressNet, self).__init__()
? ? ? ? if version not in [1.0, 1.1]:
? ? ? ? ? ? raise ValueError("Unsupported RegressNet version {version}:"
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"1.0 or 1.1 expected".format(version=version))
? ? ? ? self.export = export
? ? ? ? print(version)
? ? ? ? if version == 1.0:
? ? ? ? ? ? self.features = nn.Sequential(
? ? ? ? ? ? ? ? nn.Conv2d(3, 16, kernel_size=3,padding=(1,1), stride=1),
? ? ? ? ? ? ? ? nn.ReLU(inplace=True),
? ? ? ? ? ? ? ? nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True),
? ? ? ? ? ? ? ? Fire(16, 16, 32, 32),
? ? ? ? ? ? ? ? nn.ReLU(inplace=True),
? ? ? ? ? ? ? ? nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True),
? ? ? ? ? ? ? ? Fire(64, 32, 32, 32),
? ? ? ? ? ? ? ? nn.ReLU(inplace=True),
? ? ? ? ? ? ? ? nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=True),
? ? ? ? ? ? ? ? Fire(64, 32, 64, 64),
? ? ? ? ? ? ? ? nn.ReLU(inplace=True),
? ? ? ? ? ? ? ? Fire(128, 32, 64, 64),
? ? ? ? ? ? ? ? nn.ReLU(inplace=True),
? ? ? ? ? ? ? ? nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
? ? ? ? ? ? ? ? nn.Conv2d(128, 128, kernel_size=3,padding=(0,0), stride=2),
? ? ? ? ? ? )
? ? ? ? else:
? ? ? ? ? ? self.features = nn.Sequential(
? ? ? ? ? ? ? ? nn.Conv2d(3, 64, kernel_size=3, stride=2),
? ? ? ? ? ? ? ? nn.ReLU(inplace=True),
? ? ? ? ? ? ? ? nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
? ? ? ? ? ? ? ? Fire(64, 16, 64, 64),
? ? ? ? ? ? ? ? Fire(128, 16, 64, 64),
? ? ? ? ? ? ? ? nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
? ? ? ? ? ? ? ? Fire(128, 32, 128, 128),
? ? ? ? ? ? ? ? Fire(256, 32, 128, 128),
? ? ? ? ? ? ? ? nn.MaxPool2d(kernel_size=3, stride=2, ceil_mode=True),
? ? ? ? ? ? ? ? Fire(256, 48, 192, 192),
? ? ? ? ? ? ? ? Fire(384, 48, 192, 192),
? ? ? ? ? ? ? ? Fire(384, 64, 256, 256),
? ? ? ? ? ? ? ? Fire(512, 64, 256, 256),
? ? ? ? ? ? )
? ? ? ? # Final convolution is initialized differently form the rest
? ? ? ? #final_conv = nn.Conv2d(512, self.num_classes, kernel_size=1)
? ? ? ? #self.classifier = nn.Sequential(
? ? ? ? # ? ?nn.Dropout(p=0.5),
? ? ? ? # ? ?final_conv,
? ? ? ? # ? ?nn.ReLU(inplace=True),
? ? ? ? # ? ?nn.AdaptiveAvgPool2d((1, 1))
? ? ? ? #)
? ? ? ? self.fc= nn.Linear(128,8)
? ? ? ? MAE_Loss = torch.nn.L1Loss()
? ? ? ? self.loss = MAE_Loss
? ? ? ? for m in self.modules():
? ? ? ? ? ? if isinstance(m, nn.Conv2d):
? ? ? ? ? ? ? ? init.kaiming_uniform_(m.weight)
? ? ? ? ? ? ? ? if m.bias is not None:
? ? ? ? ? ? ? ? ? ? init.constant_(m.bias, 0)

? ? def forward(self, x):
? ? ? ? x = self.features(x)
? ? ? ? #x = x.squeeze()
? ? ? ? #x = x.flatten(0)
? ? ? ? x=x.view(-1,128)#使用view函數
? ? ? ? x = self.fc(x)
? ? ? ? #print(x)
? ? ? ? return x ?

(2)訓練工程

文件:train.py 以訓練四個關鍵點為例

import numpy as np
from math import radians, cos, sin
import torchvision.transforms as transforms
import torchvision.transforms.functional as TF
#import imutils
import torch
from PIL import Image
import random
import cv2
import xml.etree.ElementTree as ET
from torch.utils.data import Dataset
import os

import torch.nn as nn
import torchvision.models as models
import torch.nn.functional as F
import torch.nn.init as init

import torch.optim as optim
import time
from tqdm import tqdm


from model import RegressNet

class Transforms():
? ? def __init__(self):
? ? ? ? pass

? ? def rotate(self, image, landmarks, angle):
? ? ? ? # 隨機生成一個在 -angle 到 +angle 范圍內的旋轉角度
? ? ? ? angle = random.uniform(-angle, +angle)

? ? ? ? # 基于二維平面上的旋轉變換的數學特性構建旋轉矩陣
? ? ? ? transformation_matrix = torch.tensor([
? ? ? ? ? ? [+cos(radians(angle)), -sin(radians(angle))],
? ? ? ? ? ? [+sin(radians(angle)), +cos(radians(angle))]
? ? ? ? ])

? ? ? ? # 對圖像進行旋轉:相比于 PIL 的圖像旋轉計算開銷更小
? ? ? ? image = imutils.rotate(np.array(image), angle)

? ? ? ? # 將關鍵點坐標中心化:簡化旋轉變換的計算,同時確保關鍵點的變換和圖像變換的對應關系
? ? ? ? landmarks = landmarks - 0.5
? ? ? ? # 將關鍵點坐標應用旋轉矩陣
? ? ? ? new_landmarks = np.matmul(landmarks, transformation_matrix)
? ? ? ? # 恢復關鍵點坐標范圍
? ? ? ? new_landmarks = new_landmarks + 0.5

? ? ? ? return Image.fromarray(image), new_landmarks

? ? def resize(self, image, landmarks, img_size):
? ? ? ? # 調整圖像大小
? ? ? ? image = TF.resize(image, img_size)
? ? ? ? return image, landmarks

? ? def color_jitter(self, image, landmarks):
? ? ? ? # 定義顏色調整的參數:亮度、對比度、飽和度和色調
? ? ? ? color_jitter = transforms.ColorJitter(brightness=0.3,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? contrast=0.3,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? saturation=0.3,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? hue=0.1)
? ? ? ? # 對圖像進行顏色調整
? ? ? ? image = color_jitter(image)
? ? ? ? return image, landmarks

? ? def crop_face(self, image, landmarks, crops):
? ? ? ? # 獲取裁剪參數
? ? ? ? left = int(crops['left'])
? ? ? ? top = int(crops['top'])
? ? ? ? width = int(crops['width'])
? ? ? ? height = int(crops['height'])

? ? ? ? # 對圖像進行裁剪
? ? ? ? image = TF.crop(image, top, left, height, width)

? ? ? ? # 獲取裁剪后的圖像形狀
? ? ? ? img_shape = np.array(image).shape
? ? ? ? # 對關鍵點坐標進行裁剪后的調整
? ? ? ? landmarks = torch.tensor(landmarks) - torch.tensor([[left, top]])
? ? ? ? # 歸一化關鍵點坐標
? ? ? ? landmarks = landmarks / torch.tensor([img_shape[1], img_shape[0]])
? ? ? ? return image, landmarks

? ? def __call__(self, image, landmarks):
? ? ? ? # 將圖像從數組轉換為 PIL 圖像對象
? ? ? ? image = Image.fromarray(image)
? ? ? ? # 裁剪圖像并調整關鍵點

? ? ? ? # 調整圖像大小
? ? ? ? image, landmarks = self.resize(image, landmarks, (64, 64))
? ? ? ? # 對圖像進行顏色調整
? ? ? ? image, landmarks = self.color_jitter(image, landmarks)
? ? ? ? # 對圖像和關鍵點進行旋轉變換
? ? ? ? #image, landmarks = self.rotate(image, landmarks, angle=10)

? ? ? ? # 將圖像從 PIL 圖像對象轉換為 Torch 張量
? ? ? ? image = TF.to_tensor(image)
? ? ? ? # 標準化圖像像素值
? ? ? ? image = TF.normalize(image, [0.5], [0.5])
? ? ? ? return image, landmarks
?

(3)dataset定義,數據長度為8 x1,y1,x2,y2,x3,y3,x4,y4

#標簽排列規則

XXX.jpg x1/width y1/height?x2/width y2/height?x3/width y3/height?x4/width y4/height

class FaceLandmarksDataset(Dataset):
? ? def __init__(self, transform=None):

? ? ? ? #root = os.listdir(r"C:/")
? ? ? ? with open(r"C:\DL_Work\test_pics\path.txt", 'r', encoding="utf-8") as r:
? ? ? ? ? ? root = r.readlines()
? ? ? ? # 初始化變量
? ? ? ? self.image_filenames = []
? ? ? ? self.landmarks = []
? ? ? ? self.crops = []
? ? ? ? self.transform = transform
? ? ? ? self.root_dir = r'C:\DL_Work\test_pics/'

? ? ? ? # 遍歷 XML 數據:root[2] 表示 XML 中的第三個元素,即 <images> 部分,其中包含了每張圖像的標注信息
? ? ? ? for filename in root:
? ? ? ? ? ? pic_path = filename.split(" ")[0]

? ? ? ? ? ? self.image_filenames.append(os.path.join(self.root_dir, pic_path))

? ? ? ? ? ? #self.crops.append(filename)

? ? ? ? ? ? landmark = []
? ? ? ? ? ? for num in range(4):
? ? ? ? ? ? ? ? x_coordinate = int( filename.split(" ")[num*2+1])
? ? ? ? ? ? ? ? y_coordinate = int(filename.split(" ")[num*2+2])
? ? ? ? ? ? ? ? landmark.append([x_coordinate, y_coordinate])
? ? ? ? ? ? self.landmarks.append(landmark)

? ? ? ? self.landmarks = np.array(self.landmarks).astype('float32')

? ? ? ? assert len(self.image_filenames) == len(self.landmarks)

? ? def __len__(self):
? ? ? ? return len(self.image_filenames)

? ? def __getitem__(self, index):
? ? ? ? # 讀取圖像以及關鍵點坐標
? ? ? ? image = cv2.imread(self.image_filenames[index]) ?# 以彩色模式讀取圖像
? ? ? ? # image = cv2.imread(self.image_filenames[index], 0) # 以灰色模式讀取圖像
? ? ? ? landmarks = self.landmarks[index]

? ? ? ? if self.transform:
? ? ? ? ? ? # 如果存在預處理變換,應用變換
? ? ? ? ? ? image, landmarks = self.transform(image, landmarks)

? ? ? ? landmarks = landmarks - 0.5 ?# 進行中心化操作

? ? ? ? return image, landmarks


# 創建數據集對象,并應用預處理變換
dataset = FaceLandmarksDataset(Transforms())

len_valid_set = int(0.1 * len(dataset))
len_train_set = len(dataset) - len_valid_set

#print("The length of Train set is {}".format(len_train_set))
#print("The length of Valid set is {}".format(len_valid_set))

train_dataset, valid_dataset, = torch.utils.data.random_split(dataset, [len_train_set, len_valid_set])

# shuffle and batch the datasets
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=4, shuffle=True, num_workers=1)
valid_loader = torch.utils.data.DataLoader(valid_dataset, batch_size=1, shuffle=True, num_workers=1)

(4)train

def train():

? ? # 記錄每個 epoch 的訓練和驗證損失
? ? train_losses = []
? ? valid_losses = []

? ? # 設置設備
? ? device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
? ? torch.autograd.set_detect_anomaly(True)

? ? #network = Network().to(device)
? ? network = RegressNet().to(device)
? ? criterion = nn.MSELoss()
? ? optimizer = optim.Adam(network.parameters(), lr=0.0001)

? ? loss_min = np.inf
? ? num_epochs = 10

? ? start_time = time.time()
? ? for epoch in range(1, num_epochs + 1):
? ? ? ? loss_train = 0
? ? ? ? loss_valid = 0
? ? ? ? running_loss = 0

? ? ? ? network.train()

? ? ? ? for step in tqdm(range(1, len(train_loader) + 1)):
? ? ? ? ? ? images, landmarks = next(iter(train_loader))

? ? ? ? ? ? images = images.to(device)
? ? ? ? ? ? landmarks = landmarks.view(landmarks.size(0), -1).to(device)

? ? ? ? ? ? predictions = network(images)

? ? ? ? ? ? optimizer.zero_grad()
? ? ? ? ? ? loss_train_step = criterion(predictions, landmarks)
? ? ? ? ? ? loss_train_step.backward()
? ? ? ? ? ? optimizer.step()

? ? ? ? ? ? loss_train += loss_train_step.item()
? ? ? ? ? ? running_loss = loss_train / step

? ? ? ? network.eval()
? ? ? ? with torch.no_grad():
? ? ? ? ? ? for step in range(1, len(valid_loader) + 1):
? ? ? ? ? ? ? ? images, landmarks = next(iter(valid_loader))

? ? ? ? ? ? ? ? images = images.to(device)
? ? ? ? ? ? ? ? landmarks = landmarks.view(landmarks.size(0), -1).to(device)

? ? ? ? ? ? ? ? predictions = network(images)
? ? ? ? ? ? ? ? loss_valid_step = criterion(predictions, landmarks)

? ? ? ? ? ? ? ? loss_valid += loss_valid_step.item()
? ? ? ? ? ? ? ? running_loss = loss_valid / step

? ? ? ? loss_train /= len(train_loader)
? ? ? ? loss_valid /= len(valid_loader)

? ? ? ? train_losses.append(loss_train)
? ? ? ? valid_losses.append(loss_valid)

? ? ? ? print('\n--------------------------------------------------')
? ? ? ? print('Epoch: {} ?Train Loss: {:.4f} ?Valid Loss: {:.4f}'.format(epoch, loss_train, loss_valid))
? ? ? ? print('--------------------------------------------------')

? ? ? ? if loss_valid < loss_min:
? ? ? ? ? ? loss_min = loss_valid
? ? ? ? ? ? torch.save(network.state_dict(), 'plate_landmark.pth')
? ? ? ? ? ? print("\nMinimum Validation Loss of {:.4f} at epoch {}/{}".format(loss_min, epoch, num_epochs))
? ? ? ? ? ? print('Model Saved\n')

? ? print('Training Complete')
? ? print("Total Elapsed Time: {} s".format(time.time() - start_time))

if __name__ == '__main__':
? ? train()

3.導出onnx

#export.py

import torch
import torch.nn
import onnx
from onnxsim import simplify
from model import RegressNet
#device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
device = torch.device('cpu')


model = RegressNet()

model_statedict ?= torch.load(r'./plate_landmark.pth', map_location=device)
#model.eval()

model.load_state_dict(model_statedict)
input_names = ['input0']
output_names = ['output0']

x = torch.randn(1, 3, 64, 64, device=device)


torch.onnx.export(model, x, 'plate_landmark.onnx', opset_version=11, verbose=True, input_names=input_names, output_names = output_names,dynamic_axes={'input0': {0: 'batch'},
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 'output0': {0: 'batch'}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?})

onnx_model = onnx.load("plate_landmark.onnx")# 簡化模型
simplified_model, check = simplify(onnx_model)# 保存簡化后的模型
onnx.save_model(simplified_model, "plate_landmark_sim.onnx")

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18482.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18482.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18482.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[C][動態內存分配][柔性數組]詳細講解

目錄 1.動態內存函數的介紹1.malloc2.free2.calloc4.realloc 2.常見的動態內存錯誤3.C/C程序的內存開辟4.柔性數組1.是什么&#xff1f;2.柔性數組的特點3.柔性數組的使用4.柔性數組的優勢 1.動態內存函數的介紹 1.malloc 函數原型&#xff1a;void* malloc(size_t size)功能…

iOS馬甲包, AB面,H5跳轉包,開發上架

什么是馬甲包 馬甲包一般是主APP的分身或者克隆&#xff0c;也或者說是穿著馬甲的一個APP&#xff0c;脫掉馬甲&#xff0c;APP將呈現另一種樣式&#xff0c;也就是常說的AB面APP。 1. 馬甲包、AB面、白包、h5跳轉包 2.蘋果開發者 3.TG&#xff1a;APPYKJ 4.喂心&#xff1…

【AI算法崗面試八股面經【超全整理】——概率論】

AI算法崗面試八股面經【超全整理】 概率論信息論機器學習CVNLP 目錄 1、古典概型、幾何概型2、條件概率、全概率公式、貝葉斯公式3、先驗概率、后驗概率4、離散型隨機變量的常見分布5、連續型隨機變量的常見分別6、數學期望、方差7、協方差、相關系數8、獨立、互斥、不相關9.大…

【PB案例學習筆記】-11動畫顯示窗口

寫在前面 這是PB案例學習筆記系列文章的第11篇&#xff0c;該系列文章適合具有一定PB基礎的讀者。 通過一個個由淺入深的編程實戰案例學習&#xff0c;提高編程技巧&#xff0c;以保證小伙伴們能應付公司的各種開發需求。 文章中設計到的源碼&#xff0c;小凡都上傳到了gite…

ESP32 - Micropython ESP-IDF 雙線教程 WIFI (2)

ESP32 - Micropython ESP-IDF 雙線教程 WIFI ESP32 - IDF WIFI轉換為ESP32-IDF的示例代碼main/main.c 代碼解釋 ESP32 - IDF WIFI 轉換為ESP32-IDF的示例代碼 以下是使用ESP-IDF&#xff08;Espressif IoT Development Framework&#xff09;編寫的連接到Wi-Fi網絡的示例代碼…

頸源性頭痛癥狀及表

頸源性頭痛一般表現為&#xff0c;就是說從枕后一直顳側&#xff0c;到太陽穴附近&#xff0c;這個是枕小的一個疼痛&#xff0c;還有一部分人從枕后&#xff0c;沿著一個弧線&#xff08;如下圖&#xff09;的軌跡到了前額&#xff0c;到我們前額&#xff0c;這樣一個疼痛&…

Bitbucket的原理及應用詳解(一)

本系列文章簡介&#xff1a; 在數字化和全球化的今天&#xff0c;軟件開發和項目管理已經成為企業成功的關鍵因素之一。隨著團隊規模的擴大和項目的復雜化&#xff0c;如何高效地協同開發、管理代碼和確保代碼質量成為了開發者和管理者面臨的重要挑戰。Bitbucket作為一款功能強…

深入解析線程上下文切換:掌握線程上下文切換的核心原理

1. 進程與線程的基本概念 1.1 進程與線程的區別 在操作系統中&#xff0c;進程和線程是兩個基本的概念&#xff0c;它們共同構成了程序的執行環境。了解它們的區別是理解線程上下文切換的基礎。 進程&#xff1a;進程是程序的一次執行實例。它是操作系統資源分配的基本單位。…

pytest的斷言與Selenium 模擬操作的一個例子

在Python中&#xff0c;pytest是一個流行的單元測試框架&#xff0c;而Selenium是一個用于自動化瀏覽器操作的工具。結合這兩者&#xff0c;我們可以編寫自動化測試腳本來驗證網頁的行為是否符合預期。下面是一個簡單的例子&#xff0c;展示了如何使用pytest的斷言功能以及Sele…

解決在Mac下使用npm報錯:Error: EACCES: permission denied

原因說明&#xff1a;沒有足夠的權限在 /usr/local/lib/node_modules 目錄下創建文件夾 這個錯誤表明你在安裝或更新 Vue.js&#xff08;vue&#xff09;包時&#xff0c;沒有足夠的權限在 /usr/local/lib/node_modules 目錄下創建文件夾。這通常是因為默認情況下&#xff0c;普…

【頭歌-Python】文件自學引導

禁止轉載&#xff0c;原文&#xff1a;https://blog.csdn.net/qq_45801887/article/details/139258793 參考教程&#xff1a;B站視頻講解——https://space.bilibili.com/3546616042621301 如果代碼存在問題&#xff0c;麻煩大家指正 ~ ~有幫助麻煩點個贊 ~ ~ 文件自學引導 第…

算數運算符

算術運算符是用于數值類型變量計算的運算符。 它的返回結果是數值。 賦值符號 關鍵知識點&#xff1a;先看右側&#xff0c;再看左側&#xff0c;把右側的值賦值給左側的變量。 附上代碼&#xff1a; string myName "唐唐"; int myAge 18; float myHeight 177.5…

202312青少年軟件編程(Python)等級考試試卷(四級)

第 1 題 【單選題】 下列有關分治算法思想的描述不正確的是?(?) A :將問題分解成的子問題具有相同的模式 B :將問題分解出的各個子問題相互之間有公共子問題 C :當問題足夠小時,可以直接求解 D :可以將子問題的求解結果合并成原問題的解 正確答案:B 試題解析: 第 2…

ADIL簡單測試實例

參考資料&#xff1a;https://blog.csdn.net/geyichongchujianghu/article/details/130045373這個連接是Java的代碼&#xff0c;我根據它的鏈接寫了一個kotlin版本的。 AIDL&#xff08;Android Interface Definition Language&#xff09;是Android平臺上用于進程間通信&…

AI辦公自動化:kimi批量新建文件夾

工作任務&#xff1a;批量新建多個文件夾&#xff0c;每個文件夾中的年份不一樣 在kimi中輸入提示詞&#xff1a; 你是一個Python編程專家&#xff0c;要完成一個編寫關于錄制電腦上的鍵盤和鼠標操作的Python腳本的任務&#xff0c;具體步驟如下&#xff1a; 打開文件夾&…

FFmpeg編解碼的那些事(1)

看了網上很多ffmpeg的編解碼的文章和代碼&#xff0c;發現有很多文章和代碼都過時了&#xff0c;主要還是ffmpeg有很多接口都已經發生變化了。 這里簡單說一下&#xff0c;什么是編碼和解碼。 1.視頻編碼 對于視頻來說&#xff0c;可以理解為多張&#xff08;rgb或者yuv&…

Python散點圖矩陣代碼模版

本文分享Python seaborn實現散點圖矩陣代碼模版&#xff0c;節選自&#x1f449;嫌Matplotlib繁瑣&#xff1f;試試Seaborn&#xff01; 散點圖矩陣&#xff08;scatterplot matrix&#xff09;展示原始數據中所有變量兩兩之間關系&#xff0c;可以規避單一統計指標的偏差&…

二分查找算法詳講(三種版本寫法)原創

介紹: 二分查找算法&#xff08;Binary Search&#xff09;是一種在有序數組中查找目標元素的算法。 它的基本思想是通過將目標元素與數組的中間元素進行比較&#xff0c;從而將搜索范圍縮小一半。 如果目標元素等于中間元素&#xff0c;則搜索結束&#xff1b;如果目標元素小…

Neural Filters:照片恢復

Ps菜單&#xff1a;濾鏡/Neural Filters/恢復/照片恢復 Neural Filters/RESTORATION/Photo Restoration 照片恢復 Photo Restoration借助 AI 強大功能快速恢復舊照片&#xff0c;提高對比度、增強細節、消除劃痕。將此濾鏡與著色相結合以進一步增強效果。 “照片恢復”濾鏡利用…

Scikit-Learn隨機森林

Scikit-Learn隨機森林 1、隨機森林1.1、集成學習1.2、Bagging方法1.3、隨機森林算法1.4、隨機森林的優缺點2、Scikit-Learn隨機森林回歸2.1、Scikit-Learn隨機森林回歸API2.2、隨機森林回歸實踐(加州房價預測)1、隨機森林 隨機森林是一種由決策樹構成的集成算法,它在大多情況…