【機器學習】機器學習的重要技術——生成對抗網絡:理論、算法與實踐

引言

生成對抗網絡(Generative Adversarial Networks, GANs)由Ian Goodfellow等人在2014年提出,通過生成器和判別器兩個神經網絡的對抗訓練,成功實現了高質量數據的生成。GANs在圖像生成、數據增強、風格遷移等領域取得了顯著成果,成為深度學習的重要分支。本文將深入探討GANs的基本原理、核心算法及其在實際中的應用,并提供代碼示例以幫助讀者更好地理解和掌握這一技術。
在這里插入圖片描述

第一章 GANs的基本概念

1.1 什么是生成對抗網絡

生成對抗網絡由兩個相互對抗的神經網絡組成:生成器(Generator)和判別器(Discriminator)。生成器負責生成與真實數據相似的假數據,判別器負責區分真實數據和生成數據。生成器和判別器通過對抗訓練,最終生成器能夠生成逼真的數據,判別器難以區分其真偽。

1.2 GANs的基本結構
  • 生成器(Generator):接受隨機噪聲作為輸入,生成與真實數據分布相似的樣本。
  • 判別器(Discriminator):接受真實數據和生成數據作為輸入,輸出區分它們的概率。

GANs的目標是通過對抗訓練,使得生成器生成的數據與真實數據無法區分,從而實現高質量的數據生成。

1.3 GANs的訓練過程

GANs的訓練過程可以概括為以下步驟:

  1. 初始化:隨機初始化生成器和判別器的參數。
  2. 判別器訓練:固定生成器的參數,更新判別器的參數,使其能夠更好地區分真實數據和生成數據。
  3. 生成器訓練:固定判別器的參數,更新生成器的參數,使其生成的數據能夠欺騙判別器。
  4. 迭代:重復步驟2和3,直到生成器生成的數據與真實數據難以區分。

第二章 GANs的核心算法

2.1 標準GANs

標準GANs的損失函數由生成器和判別器的對抗損失組成。判別器的目標是最大化正確分類的概率,生成器的目標是最小化生成數據被判別器識別為假的概率。

import tensorflow as tf
from tensorflow.keras import layers# 生成器模型
def build_generator():model = tf.keras.Sequential()model.add(layers.Dense(256, activation='relu', input_dim=100))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(512, activation='relu'))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(1024, activation='relu'))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(28 * 28 * 1, activation='tanh'))model.add(layers.Reshape((28, 28, 1)))return model# 判別器模型
def build_discriminator():model = tf.keras.Sequential()model.add(layers.Flatten(input_shape=(28, 28, 1)))model.add(layers.Dense(512, activation='relu'))model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(256, activation='relu'))model.add(layers.LeakyReLU(alpha=0.2))model.add(layers.Dense(1, activation='sigmoid'))return model# 編譯模型
generator = build_generator()
discriminator = build_discriminator()
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])# GAN模型
discriminator.trainable = False
gan_input = layers.Input(shape=(100,))
generated_image = generator(gan_input)
gan_output = discriminator(generated_image)
gan = tf.keras.models.Model(gan_input, gan_output)
gan.compile(optimizer='adam', loss='binary_crossentropy')# 加載MNIST數據集
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype('float32') - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=3)# 訓練GANs
batch_size = 128
epochs = 10000
half_batch = int(batch_size / 2)for epoch in range(epochs):# 訓練判別器idx = np.random.randint(0, x_train.shape[0], half_batch)real_images = x_train[idx]noise = np.random.normal(0, 1, (half_batch, 100))generated_images = generator.predict(noise)d_loss_real = discriminator.train_on_batch(real_images, np.ones((half_batch, 1)))d_loss_fake = discriminator.train_on_batch(generated_images, np.zeros((half_batch, 1)))d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)# 訓練生成器noise = np.random.normal(0, 1, (batch_size, 100))valid_y = np.array([1] * batch_size)g_loss = gan.train_on_batch(noise, valid_y)if epoch % 1000 == 0:print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")
2.2 深度卷積生成對抗網絡(DCGAN)

DCGAN通過在生成器和判別器中引入卷積層,顯著提高了圖像生成的質量。以下是一個基于DCGAN的示例。

def build_generator():model = tf.keras.Sequential()model.add(layers.Dense(7 * 7 * 256, use_bias=False, input_shape=(100,)))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Reshape((7, 7, 256)))model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))return modeldef build_discriminator():model = tf.keras.Sequential()model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1]))model.add(layers.LeakyReLU())model.add(layers.Dropout(0.3))model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))model.add(layers.LeakyReLU())model.add(layers.Dropout(0.3))model.add(layers.Flatten())model.add(layers.Dense(1))return modelgenerator = build_generator()
discriminator = build_discriminator()# 編譯判別器
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])# 編譯GAN模型
discriminator.trainable = False
gan_input = layers.Input(shape=(100,))
generated_image = generator(gan_input)
gan_output = discriminator(generated_image)
gan = tf.keras.models.Model(gan_input, gan_output)
gan.compile(optimizer='adam', loss='binary_crossentropy')# 加載MNIST數據集
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype('float32') - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=3)# 訓練DCGAN
batch_size = 128
epochs = 10000
half_batch = int(batch_size / 2)for epoch in range(epochs):# 訓練判別器idx = np.random.randint(0, x_train.shape[0], half_batch)real_images = x_train[idx]noise = np.random.normal(0, 1, (half_batch, 100))generated_images = generator.predict(noise)d_loss_real = discriminator.train_on_batch(real_images, np.ones((half_batch, 1)))d_loss_fake = discriminator.train_on_batch(generated_images, np.zeros((half_batch, 1)))d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)# 訓練生成器noise = np.random.normal(0, 1, (batch_size, 100))valid_y = np.array([1] * batch_size)g_loss = gan.train_on_batch(noise, valid_y)if epoch % 1000 == 0:print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")
2.3 條件生成對抗網絡(Conditional GAN)

條件生成對抗網絡(Conditional GAN, cGAN)通過在生成器和判別器中引入條件變量,使生成的數據能夠滿足特定條件。

def build_generator():model = tf.keras.Sequential()model.add(layers.Dense(7 * 7 * 256, use_bias=False, input_shape=(110,)))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Reshape((7, 7, 256)))model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))model.add(layers.BatchNormalization())model.add(layers.LeakyReLU())model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))return modeldef build_discriminator():model = tf.keras.Sequential()model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 11]))model.add(layers.LeakyReLU())model.add(layers.Dropout(0.3))model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))model.add(layers.LeakyReLU())model.add(layers.Dropout(0.3))model.add(layers.Flatten())model.add(layers.Dense(1))return modelgenerator = build_generator()
discriminator = build_discriminator()# 編譯判別器
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])# 編譯cGAN模型
discriminator.trainable = False
noise_input = layers.Input(shape=(100,))
label_input = layers.Input(shape=(10,))
gan_input = layers.Concatenate()([noise_input, label_input])
generated_image = generator(gan_input)
label_image = layers.Concatenate()([generated_image, label_input])
gan_output = discriminator(label_image)
cgan = tf.keras.models.Model([noise_input, label_input], gan_output)
cgan.compile(optimizer='adam', loss='binary_crossentropy')# 加載MNIST數據集
(x_train, y_train), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype('float32') - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=3)
y_train = tf.keras.utils.to_categorical(y_train, 10)# 訓練cGAN
batch_size = 128
epochs = 10000
half_batch = int(batch_size / 2)for epoch in range(epochs):# 訓練判別器idx = np.random.randint(0, x_train.shape[0], half_batch)real_images = x_train[idx]real_labels = y_train[idx]noise = np.random.normal(0, 1, (half_batch, 100))generated_labels = np.random.randint(0, 10, half_batch)generated_labels = tf.keras.utils.to_categorical(generated_labels, 10)generated_images = generator.predict([noise, generated_labels])real_images_with_labels = np.concatenate([real_images, real_labels], axis=3)generated_images_with_labels = np.concatenate([generated_images, generated_labels], axis=3)d_loss_real = discriminator.train_on_batch(real_images_with_labels, np.ones((half_batch, 1)))d_loss_fake = discriminator.train_on_batch(generated_images_with_labels, np.zeros((half_batch, 1)))d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)# 訓練生成器noise = np.random.normal(0, 1, (batch_size, 100))valid_y = np.array([1] * batch_size)labels = np.random.randint(0, 10, batch_size)labels = tf.keras.utils.to_categorical(labels, 10)g_loss = cgan.train_on_batch([noise, labels], valid_y)if epoch % 1000 == 0:print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")

在這里插入圖片描述

第三章 GANs的應用實例

3.1 圖像生成

GANs在圖像生成任務中表現出色,可以生成高質量的圖像。以下是一個使用DCGAN生成手寫數字圖像的示例。

import matplotlib.pyplot as plt# 生成手寫數字圖像
noise = np.random.normal(0, 1, (25, 100))
generated_images = generator.predict(noise)# 繪制生成的圖像
plt.figure(figsize=(10, 10))
for i in range(generated_images.shape[0]):plt.subplot(5, 5, i + 1)plt.imshow(generated_images[i, :, :, 0], cmap='gray')plt.axis('off')
plt.tight_layout()
plt.show()
3.2 數據增強

GANs可以用于數據增強,通過生成新的樣本擴展訓練數據集,從而提高模型的泛化能力。以下是一個使用cGAN生成帶標簽的手寫數字圖像的示例。

# 生成帶標簽的手寫數字圖像
noise = np.random.normal(0, 1, (25, 100))
labels = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9] * 2 + [0, 1, 2, 3, 4])
labels = tf.keras.utils.to_categorical(labels, 10)
generated_images = generator.predict([noise, labels])# 繪制生成的圖像
plt.figure(figsize=(10, 10))
for i in range(generated_images.shape[0]):plt.subplot(5, 5, i + 1)plt.imshow(generated_images[i, :, :, 0], cmap='gray')plt.axis('off')
plt.tight_layout()
plt.show()
3.3 風格遷移

GANs可以用于風格遷移,通過將一種圖像的內容與另一種圖像的風格結合,生成具有新風格的圖像。以下是一個使用CycleGAN進行圖像風格遷移的示例。

import tensorflow as tf
import tensorflow_addons as tfa
from tensorflow.keras import layersdef residual_block(x, filters, kernel_size=3):fx = layers.Conv2D(filters, kernel_size, padding='same')(x)fx = tfa.layers.InstanceNormalization()(fx)fx = layers.ReLU()(fx)fx = layers.Conv2D(filters, kernel_size, padding='same')(fx)fx = tfa.layers.InstanceNormalization()(fx)x = layers.Add()([x, fx])return xdef build_generator():inputs = layers.Input(shape=[256, 256, 3])x = layers.Conv2D(64, 7, padding='same')(inputs)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)x = layers.Conv2D(128, 3, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)x = layers.Conv2D(256, 3, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)for _ in range(9):x = residual_block(x, 256)x = layers.Conv2DTranspose(128, 3, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)x = layers.Conv2DTranspose(64, 3, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.ReLU()(x)x = layers.Conv2D(3, 7, padding='same')(x)x = layers.Activation('tanh')(x)return tf.keras.Model(inputs, x)def build_discriminator():inputs = layers.Input(shape=[256, 256, 3])x = layers.Conv2D(64, 4, strides=2, padding='same')(inputs)x = layers.LeakyReLU(alpha=0.2)(x)x = layers.Conv2D(128, 4, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.LeakyReLU(alpha=0.2)(x)x = layers.Conv2D(256, 4, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.LeakyReLU(alpha=0.2)(x)x = layers.Conv2D(512, 4, strides=2, padding='same')(x)x = tfa.layers.InstanceNormalization()(x)x = layers.LeakyReLU(alpha=0.2)(x)x = layers.Conv2D(1, 4, padding='same')(x)return tf.keras.Model(inputs, x)# 構建CycleGAN模型
generator_g = build_generator()
generator_f = build_generator()
discriminator_x = build_discriminator()
discriminator_y = build_discriminator()# 編譯模型
generator_g.compile(optimizer='adam', loss='mse')
generator_f.compile(optimizer='adam', loss='mse')
discriminator_x.compile(optimizer='adam', loss='mse')
discriminator_y.compile(optimizer='adam', loss='mse')# 訓練CycleGAN
# 訓練數據準備和訓練代碼略# 使用CycleGAN進行風格遷移
def generate_images(model, test_input):prediction = model(test_input)plt.figure(figsize=(12, 12))display_list = [test_input[0], prediction[0]]title = ['Input Image', 'Predicted Image']for i in range(2):plt.subplot(1, 2, i + 1)plt.title(title[i])plt.imshow(display_list[i] * 0.5 + 0.5)plt.axis('off')plt.show()# 測試圖像
test_image = tf.expand_dims(tf.image.resize(test_image, (256, 256)), axis=0) / 127.5 - 1
generate_images(generator_g, test_image)

在這里插入圖片描述

第四章 GANs的未來發展與挑戰

4.1 訓練穩定性

GANs的訓練過程容易出現不穩定性,如模式崩潰(mode collapse)和梯度消失等問題。研究如何提高GANs訓練的穩定性是一個重要的方向。

4.2 模型評價

如何有效評估GANs生成數據的質量和多樣性是一個挑戰。研究方向包括開發更好的評價指標,如Frechet Inception Distance(FID)和Inception Score(IS)等。

4.3 應用擴展

GANs的應用范圍不斷擴大,研究如何在更多領域和任務中應用GANs,如文本生成、音頻生成和科學模擬等,是一個重要的方向。

結論

生成對抗網絡作為一種強大的生成模型,通過生成器和判別器的對抗訓練,實現了高質量的數據生成和多種應用。本文詳細介紹了GANs的基本概念、核心算法及其在實際中的應用,并提供了具體的代碼示例,幫助讀者深入理解和掌握這一技術。希望本文能夠為您進一步探索和應用生成對抗網絡提供有價值的參考。

在這里插入圖片描述

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

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

相關文章

leetCode.97. 交錯字符串

leetCode.97. 交錯字符串 題目思路 代碼 class Solution { public:bool isInterleave(string s1, string s2, string s3) {int n s1.size(), m s2.size();if ( s3.size() ! n m ) return false;vector<vector<bool>> f( n 1, vector<bool> (m 1));s1 …

C語言使用void *類型作為函數傳參

C語言使用void *怎么理解&#xff1a; 根據本人的理解&#xff0c;他就是指向操作數據區的首地址而已 凡是void指的數據區都要進行第二次初始化數據類型&#xff08;即dtype p(dtype)pdata&#xff09;*。 舉兩個例子&#xff1a; 傳入函數&#xff1a; void tx_data(void …

Sparse4D v3: Advancing End-to-End 3D Detection and Tracking

Sparse4D v3: Advancing End-to-End 3D Detection and Tracking 相關內容&#xff1a;總覽&#xff0c;Sparse4D v1&#xff0c;Sparse4D v2&#xff0c; 單位&#xff1a;地平線(Sparse4D v1 v2 原班人馬) GitHub&#xff1a;https://github.com/HorizonRobotics/Sparse4D …

昇思25天學習打卡營第5天 | 網絡構建

目錄 1.定義模型類 2.模型層 nn.Flatten nn.Dense nn.ReLU nn.SequentialCell nn.Softmax 3.模型參數 代碼實現&#xff1a; 總結 神經網絡模型是由神經網絡層和Tensor操作構成的&#xff0c; mindspore.nn提供了常見神經網絡層的實現&#xff0c; 在MindSpore中&a…

啟動spring boot項目停止 提示80端口已經被占用

可能的情況: 檢查并結束占用進程: 首先,你需要確定哪個進程正在使用80端口。在Windows上,可以通過命令行輸入netstat -ano | findstr LISTENING | findstr :80來查看80端口的PID,然后在任務管理器中結束該進程。在

AI智能客服項目拆解(1) 產品大綱

本文作為拆解AI智能客服項目的首篇&#xff0c;以介紹產品大綱為主。后續以某AI智能客服產品為例&#xff0c;拆解相關技術細節。 AI智能客服是一種基于人工智能技術的客戶服務解決方案&#xff0c;旨在提高客戶滿意度和優化企業運營。利用人工智能和自然語言處理技術&#xff…

MySQL之索引失效的情況

什么情況下索引會失效&#xff1f; 違反最左前綴原則范圍查詢右邊的列不能使用索引不要在索引列上進行運算操作字符串不加單引號導致索引失效以%開頭的like模糊查詢 什么情況下索引會失效&#xff1f; 示例&#xff0c;有user表如下 CREATE TABLE user (id bigint(20) NOT NU…

實驗1 多層感知器設計(MLP)

1.實驗目的 掌握多層感知器的原理。掌握多層感知器的設計、訓練和測試。2.實驗要求 設計一個多層感知器,用于對給定的數據進行分類。要求代碼格式規范,注釋齊全,程序可正常運行。 3.模型設計 實驗設計一個多層感知機,三層機構,只含一個隱藏層,輸入層,隱藏層,輸出層 1…

JAVA期末速成庫(11)第十二章

一、習題介紹 第十二章 Check Point&#xff1a;P454 12.1&#xff0c;12.9&#xff0c;12.10&#xff0c;12,12 二、習題及答案 12.1 What is the advantage of using exception handling? 12.1使用異常處理的優勢是什么? 答:使用異常處理有以下優勢&#xff1a; 1. 提高…

C++ 模板類的示例-數組

類模板可以有非通用類型參數&#xff1a;1&#xff09;通常是整型&#xff08;C20標準可以用其它的類型&#xff09;&#xff1b;2&#xff09;實例化模板時必須用常量表達式&#xff1b;3&#xff09;模板中不能修改參數的值&#xff1b;4&#xff09;可以為非通用類型參數提供…

Android中使用performClick觸發點擊事件

Android中使用performClick觸發點擊事件 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討在Android開發中如何使用 performClick() 方法來觸發點擊…

數據庫-python SQLite3

數據庫-python SQLite3 一&#xff1a;sqlite3 簡介二: sqlite3 流程1> demo2> sqlite3 流程 三&#xff1a;sqlite3 step1> create table2> insert into3> update4> select1. fetchall()2. fetchone()3. fetchmany() 5> delete6> other step 四&#…

Spark join數據傾斜調優

Spark中常見的兩種數據傾斜現象如下 stage部分task執行特別慢 一般情況下是某個task處理的數據量遠大于其他task處理的數據量&#xff0c;當然也不排除是程序代碼沒有冗余&#xff0c;異常數據導致程序運行異常。 作業重試多次某幾個task總會失敗 常見的退出碼143、53、137…

【電路筆記】-放大器類型

放大器類型 文章目錄 放大器類型1、概述2、關于偏置的注意事項3、A類(Class A)放大器4、B類(Class B)放大器5、AB類(Class AB)放大器6、C類(Class C)放大器7、總結1、概述 放大器通常根據輸出級的結構進行分類。 事實上,功率放大確實發生在該階段,因此輸出信號的質量和…

Arduino (esp ) 下String的內存釋放

在個人的開源項目 GitHub - StarCompute/tftziku: 這是一個通過單片機在各種屏幕上顯示中文的解決方案 中為了方便快速檢索使用了string&#xff0c;于是這個string在esp8266中占了40多k,原本以為當string設置為""的時候這個40k就可以回收&#xff0c;結果發覺不行…

【JS異步編程】async/await——用同步代碼寫異步

歷史小劇場 懂得暴力的人&#xff0c;是強壯的&#xff1b;懂得克制暴力的人&#xff0c;才是強大的。----《明朝那些事兒》 什么是 async/await async: 聲明一個異步函數 自動將常規函數轉換成Promise&#xff0c;返回值也是一個Promise對象&#xff1b;只有async函數內部的異…

Java SE入門及基礎(59) 線程的實現(上) 線程的創建方式 線程內存模型 線程安全

目錄 線程&#xff08;上&#xff09; 1. 線程的創建方式 Thread類常用構造方法 Thread類常用成員方法 Thread類常用靜態方法 示例 總結 2. 線程內存模型 3.線程安全 案例 代碼實現 執行結果 線程&#xff08;上&#xff09; 1. 線程的創建方式 An application t…

利用 Docker 簡化 Nacos 部署:快速搭建 Nacos 服務

利用 Docker 簡化 Nacos 部署&#xff1a;快速搭建 Nacos 服務 引言 在微服務架構中&#xff0c;服務注冊與發現是確保服務間通信順暢的關鍵組件。Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;作為阿里巴巴開源的一個服務發現和配置管理平臺&…

任務調度器——任務切換

一、開啟任務調度器 函數原型&#xff1a; void vTaskStartScheduler( void ) 作用&#xff1a;用于啟動任務調度器&#xff0c;任務調度器啟動后&#xff0c; FreeRTOS 便會開始進行任務調度 內部實現機制&#xff08;以動態創建為例&#xff09;&#xff1a; &#xff0…

Linux 安裝、配置Tomcat 的HTTPS

Linux 安裝 、配置Tomcat的HTTPS 安裝Tomcat 這里選擇的是 tomcat 10.X ,需要Java 11及更高版本 下載頁 ->Binary Distributions ->Core->選擇 tar.gz包 下載、上傳到內網服務器 /opt 目錄tar -xzf 解壓將解壓的根目錄改名為 tomat-10 并移動到 /opt 下, 形成個人…