TensorFlow学习笔记——(13)RNN、LSTM、GRU实现股票预测

2023-05-16

文章目录

      • 一、RNN股票预测
      • 二、LSTM股票预测
        • 1、长短记忆网络介绍
        • 2、TF描述LSTM层
        • 3、实验代码
      • 三、GRU股票预测
        • 1、GRU网络介绍
        • 2、TF描述GRU层
        • 3、实验代码

一、RNN股票预测

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dropout, Dense, SimpleRNN
import matplotlib.pyplot as plt
import os
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import math

# 读取贵州茅台日k线数据到变量maotai
maotai = pd.read_csv('./SH600519.csv')  # 读取股票文件

training_set = maotai.iloc[0:2426 - 300, 2:3].values  # 前(2426-300=2126)天的开盘价作为训练集,表格从0开始计数,2:3 是提取[2:3)列,前闭后开,故提取出C列开盘价
test_set = maotai.iloc[2426 - 300:, 2:3].values  # 后300天的开盘价作为测试集

# 对开盘价进行归一化
sc = MinMaxScaler(feature_range=(0, 1))  # 定义归一化:归一化到(0,1)之间
training_set_scaled = sc.fit_transform(training_set)  # 求得训练集的最大值,最小值这些训练集固有的属性,并在训练集上进行归一化
test_set = sc.transform(test_set)  # 利用训练集的属性对测试集进行归一化

# 建立空列表用于接收输入特征和标签
x_train = []
y_train = []

x_test = []
y_test = []

# 生成数据集train、test
# 测试集:csv表格中前2426-300=2126天数据
# 利用for循环,遍历整个训练集,提取训练集中连续60天的开盘价作为输入特征x_train,第61天的数据作为标签,for循环共构建2426-300-60=2066组数据。
for i in range(60, len(training_set_scaled)):
    x_train.append(training_set_scaled[i - 60:i, 0])
    y_train.append(training_set_scaled[i, 0])
# 对训练集进行打乱
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)
# 将训练集由list格式变为array格式
x_train, y_train = np.array(x_train), np.array(y_train)

# 使x_train符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]。
# 此处整个数据集送入,送入样本数为x_train.shape[0]即2066组数据;输入60个开盘价,预测出第61天的开盘价,循环核时间展开步数为60; 每个时间步送入的特征是某一天的开盘价,只有1个数据,故每个时间步输入特征个数为1
x_train = np.reshape(x_train, (x_train.shape[0], 60, 1))
# 测试集:csv表格中后300天数据
# 利用for循环,遍历整个测试集,提取测试集中连续60天的开盘价作为输入特征x_train,第61天的数据作为标签,for循环共构建300-60=240组数据。
for i in range(60, len(test_set)):
    x_test.append(test_set[i - 60:i, 0])
    y_test.append(test_set[i, 0])
# 测试集变array并reshape为符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]
x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (x_test.shape[0], 60, 1))

# 搭建神经网络
model = tf.keras.Sequential([
    # 第一层:循环计算层,记忆体80个,每个时间步推送ht给下一层
    SimpleRNN(80, return_sequences=True),
    Dropout(0.2),
    # 第二层:循环计算层,记忆体100个
    SimpleRNN(100),
    Dropout(0.2),
    # 由于输出值是第61天开盘价,只有一个,所以dense是1
    Dense(1)
])

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss='mean_squared_error')  # 损失函数用均方误差
# 该应用只观测loss数值,不观测准确率,所以删去metrics选项,一会在每个epoch迭代显示时只显示loss值

checkpoint_save_path = "./checkpoint/rnn_stock.ckpt"

if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
                                                 save_weights_only=True,
                                                 save_best_only=True,
                                                 monitor='val_loss')

history = model.fit(x_train, y_train, batch_size=64, epochs=50, validation_data=(x_test, y_test), validation_freq=1,
                    callbacks=[cp_callback])

model.summary()

file = open('./weights.txt', 'w')  # 参数提取
for v in model.trainable_variables:
    file.write(str(v.name) + '\n')
    file.write(str(v.shape) + '\n')
    file.write(str(v.numpy()) + '\n')
file.close()

loss = history.history['loss']
val_loss = history.history['val_loss']

plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()

################## predict ######################
# 测试集输入模型进行预测
predicted_stock_price = model.predict(x_test)
# 对预测数据还原---从(0,1)反归一化到原始范围
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
# 对真实数据还原---从(0,1)反归一化到原始范围
real_stock_price = sc.inverse_transform(test_set[60:])
# 画出真实数据和预测数据的对比曲线
plt.plot(real_stock_price, color='red', label='MaoTai Stock Price')
plt.plot(predicted_stock_price, color='blue', label='Predicted MaoTai Stock Price')
plt.title('MaoTai Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('MaoTai Stock Price')
plt.legend()
plt.show()

##########evaluate##############
# calculate MSE 均方误差 ---> E[(预测值-真实值)^2] (预测值减真实值求平方后求均值)
mse = mean_squared_error(predicted_stock_price, real_stock_price)
# calculate RMSE 均方根误差--->sqrt[MSE]    (对均方误差开方)
rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price))
# calculate MAE 平均绝对误差----->E[|预测值-真实值|](预测值减真实值求绝对值后求均值)
mae = mean_absolute_error(predicted_stock_price, real_stock_price)
print('均方误差: %.6f' % mse)
print('均方根误差: %.6f' % rmse)
print('平均绝对误差: %.6f' % mae)

二、LSTM股票预测

1、长短记忆网络介绍

在这里插入图片描述
三个门限:
都是当前时刻的输入特征xt和上个时刻的短期记忆ht-1的函数。其中,Wi、Wf、Wo是待训练参数矩阵,bi、bf、bo是待训练偏置项,都经过sigmoid激活函数,使门限的范围在0到1之间。

细胞态表示长期记忆,等于上个时刻的长期记忆乘遗忘门,加上当前时刻归纳出的新知识乘以输入门。

记忆体属于短期记忆,属于长期记忆的一部分,是细胞态过tanh激活函数乘以输出门的结果。

候选态表示归纳出的待存入细胞态的新知识,是当前时刻的输入特征xt和上个时刻的短期记忆ht-1的函数,Wc是待训练参数矩阵,bc是待训练偏置项。

2、TF描述LSTM层

在这里插入图片描述

3、实验代码

import numpy as np
import tensorflow as tf
# 将这里的RNN换成LSTM
from tensorflow.keras.layers import Dropout, Dense, LSTM
import matplotlib.pyplot as plt
import os
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import math

maotai = pd.read_csv('./SH600519.csv')  # 读取股票文件

training_set = maotai.iloc[0:2426 - 300, 2:3].values  # 前(2426-300=2126)天的开盘价作为训练集,表格从0开始计数,2:3 是提取[2:3)列,前闭后开,故提取出C列开盘价
test_set = maotai.iloc[2426 - 300:, 2:3].values  # 后300天的开盘价作为测试集

# 归一化
sc = MinMaxScaler(feature_range=(0, 1))  # 定义归一化:归一化到(0,1)之间
training_set_scaled = sc.fit_transform(training_set)  # 求得训练集的最大值,最小值这些训练集固有的属性,并在训练集上进行归一化
test_set = sc.transform(test_set)  # 利用训练集的属性对测试集进行归一化

x_train = []
y_train = []

x_test = []
y_test = []

# 测试集:csv表格中前2426-300=2126天数据
# 利用for循环,遍历整个训练集,提取训练集中连续60天的开盘价作为输入特征x_train,第61天的数据作为标签,for循环共构建2426-300-60=2066组数据。
for i in range(60, len(training_set_scaled)):
    x_train.append(training_set_scaled[i - 60:i, 0])
    y_train.append(training_set_scaled[i, 0])
# 对训练集进行打乱
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)
# 将训练集由list格式变为array格式
x_train, y_train = np.array(x_train), np.array(y_train)

# 使x_train符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]。
# 此处整个数据集送入,送入样本数为x_train.shape[0]即2066组数据;输入60个开盘价,预测出第61天的开盘价,循环核时间展开步数为60; 每个时间步送入的特征是某一天的开盘价,只有1个数据,故每个时间步输入特征个数为1
x_train = np.reshape(x_train, (x_train.shape[0], 60, 1))
# 测试集:csv表格中后300天数据
# 利用for循环,遍历整个测试集,提取测试集中连续60天的开盘价作为输入特征x_train,第61天的数据作为标签,for循环共构建300-60=240组数据。
for i in range(60, len(test_set)):
    x_test.append(test_set[i - 60:i, 0])
    y_test.append(test_set[i, 0])
# 测试集变array并reshape为符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]
x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (x_test.shape[0], 60, 1))

model = tf.keras.Sequential([
    # 与RNN预测股票相比,只需要改变这里
    LSTM(80, return_sequences=True),
    Dropout(0.2),
    LSTM(100),
    Dropout(0.2),
    Dense(1)
])

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss='mean_squared_error')  # 损失函数用均方误差
# 该应用只观测loss数值,不观测准确率,所以删去metrics选项,一会在每个epoch迭代显示时只显示loss值

checkpoint_save_path = "./checkpoint/LSTM_stock.ckpt"

if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
                                                 save_weights_only=True,
                                                 save_best_only=True,
                                                 monitor='val_loss')

history = model.fit(x_train, y_train, batch_size=64, epochs=50, validation_data=(x_test, y_test), validation_freq=1,
                    callbacks=[cp_callback])

model.summary()

file = open('./weights.txt', 'w')  # 参数提取
for v in model.trainable_variables:
    file.write(str(v.name) + '\n')
    file.write(str(v.shape) + '\n')
    file.write(str(v.numpy()) + '\n')
file.close()

loss = history.history['loss']
val_loss = history.history['val_loss']

plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()

################## predict ######################
# 测试集输入模型进行预测
predicted_stock_price = model.predict(x_test)
# 对预测数据还原---从(0,1)反归一化到原始范围
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
# 对真实数据还原---从(0,1)反归一化到原始范围
real_stock_price = sc.inverse_transform(test_set[60:])
# 画出真实数据和预测数据的对比曲线
plt.plot(real_stock_price, color='red', label='MaoTai Stock Price')
plt.plot(predicted_stock_price, color='blue', label='Predicted MaoTai Stock Price')
plt.title('MaoTai Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('MaoTai Stock Price')
plt.legend()
plt.show()

##########evaluate##############
# calculate MSE 均方误差 ---> E[(预测值-真实值)^2] (预测值减真实值求平方后求均值)
mse = mean_squared_error(predicted_stock_price, real_stock_price)
# calculate RMSE 均方根误差--->sqrt[MSE]    (对均方误差开方)
rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price))
# calculate MAE 平均绝对误差----->E[|预测值-真实值|](预测值减真实值求绝对值后求均值)
mae = mean_absolute_error(predicted_stock_price, real_stock_price)
print('均方误差: %.6f' % mse)
print('均方根误差: %.6f' % rmse)
print('平均绝对误差: %.6f' % mae)

三、GRU股票预测

1、GRU网络介绍

GRU使记忆体ht融合了长期记忆和短期记忆
在这里插入图片描述

2、TF描述GRU层

在这里插入图片描述

3、实验代码

import numpy as np
import tensorflow as tf
# 只需要在这里导入GRU
from tensorflow.keras.layers import Dropout, Dense, GRU
import matplotlib.pyplot as plt
import os
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import math

maotai = pd.read_csv('./SH600519.csv')  # 读取股票文件

training_set = maotai.iloc[0:2426 - 300, 2:3].values  # 前(2426-300=2126)天的开盘价作为训练集,表格从0开始计数,2:3 是提取[2:3)列,前闭后开,故提取出C列开盘价
test_set = maotai.iloc[2426 - 300:, 2:3].values  # 后300天的开盘价作为测试集

# 归一化
sc = MinMaxScaler(feature_range=(0, 1))  # 定义归一化:归一化到(0,1)之间
training_set_scaled = sc.fit_transform(training_set)  # 求得训练集的最大值,最小值这些训练集固有的属性,并在训练集上进行归一化
test_set = sc.transform(test_set)  # 利用训练集的属性对测试集进行归一化

x_train = []
y_train = []

x_test = []
y_test = []

# 测试集:csv表格中前2426-300=2126天数据
# 利用for循环,遍历整个训练集,提取训练集中连续60天的开盘价作为输入特征x_train,第61天的数据作为标签,for循环共构建2426-300-60=2066组数据。
for i in range(60, len(training_set_scaled)):
    x_train.append(training_set_scaled[i - 60:i, 0])
    y_train.append(training_set_scaled[i, 0])
# 对训练集进行打乱
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)
# 将训练集由list格式变为array格式
x_train, y_train = np.array(x_train), np.array(y_train)

# 使x_train符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]。
# 此处整个数据集送入,送入样本数为x_train.shape[0]即2066组数据;输入60个开盘价,预测出第61天的开盘价,循环核时间展开步数为60; 每个时间步送入的特征是某一天的开盘价,只有1个数据,故每个时间步输入特征个数为1
x_train = np.reshape(x_train, (x_train.shape[0], 60, 1))
# 测试集:csv表格中后300天数据
# 利用for循环,遍历整个测试集,提取测试集中连续60天的开盘价作为输入特征x_train,第61天的数据作为标签,for循环共构建300-60=240组数据。
for i in range(60, len(test_set)):
    x_test.append(test_set[i - 60:i, 0])
    y_test.append(test_set[i, 0])
# 测试集变array并reshape为符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]
x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (x_test.shape[0], 60, 1))

model = tf.keras.Sequential([
    # 只需将这里改为GRU层,其他和RNN一样
    GRU(80, return_sequences=True),
    Dropout(0.2),
    GRU(100),
    Dropout(0.2),
    Dense(1)
])

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),
              loss='mean_squared_error')  # 损失函数用均方误差
# 该应用只观测loss数值,不观测准确率,所以删去metrics选项,一会在每个epoch迭代显示时只显示loss值

checkpoint_save_path = "./checkpoint/stock.ckpt"

if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
                                                 save_weights_only=True,
                                                 save_best_only=True,
                                                 monitor='val_loss')

history = model.fit(x_train, y_train, batch_size=64, epochs=50, validation_data=(x_test, y_test), validation_freq=1,
                    callbacks=[cp_callback])

model.summary()

file = open('./weights.txt', 'w')  # 参数提取
for v in model.trainable_variables:
    file.write(str(v.name) + '\n')
    file.write(str(v.shape) + '\n')
    file.write(str(v.numpy()) + '\n')
file.close()

loss = history.history['loss']
val_loss = history.history['val_loss']

plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()

################## predict ######################
# 测试集输入模型进行预测
predicted_stock_price = model.predict(x_test)
# 对预测数据还原---从(0,1)反归一化到原始范围
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
# 对真实数据还原---从(0,1)反归一化到原始范围
real_stock_price = sc.inverse_transform(test_set[60:])
# 画出真实数据和预测数据的对比曲线
plt.plot(real_stock_price, color='red', label='MaoTai Stock Price')
plt.plot(predicted_stock_price, color='blue', label='Predicted MaoTai Stock Price')
plt.title('MaoTai Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('MaoTai Stock Price')
plt.legend()
plt.show()

##########evaluate##############
# calculate MSE 均方误差 ---> E[(预测值-真实值)^2] (预测值减真实值求平方后求均值)
mse = mean_squared_error(predicted_stock_price, real_stock_price)
# calculate RMSE 均方根误差--->sqrt[MSE]    (对均方误差开方)
rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price))
# calculate MAE 平均绝对误差----->E[|预测值-真实值|](预测值减真实值求绝对值后求均值)
mae = mean_absolute_error(predicted_stock_price, real_stock_price)
print('均方误差: %.6f' % mse)
print('均方根误差: %.6f' % rmse)
print('平均绝对误差: %.6f' % mae)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TensorFlow学习笔记——(13)RNN、LSTM、GRU实现股票预测 的相关文章

  • Qt如何使QTreeWidget始终保持展开?

    文章已更新 xff0c 最新地址 xff1a http www fearlazy com index php post 122 html 有时候我们在使用树形控件实现项目分组功能时 xff0c 不希望点击组名 即顶层Item 时收缩 此时应
  • Received status code 400 from server: Bad Request

    一 报错信息 FAILURE span class token operator span span class token class name Build span failed span class token keyword wit
  • wangEditor使用教程

    1 安装 xff08 vue2 xff09 yarn add 64 wangeditor editor 或者 npm install 64 wangeditor editor save yarn add 64 wangeditor edit
  • 微信小程序之问卷调查

    登录界面 login js span class token comment miniprogram pages login login js span span class token function Page span span cl
  • NISP

    文章目录 NISP七月份练习01NISP七月份练习02NISP七月份练习03NISP七月份练习04NISP七月份练习05NISP七月份练习06NISP七月份练习07NISP七月份练习08NISP七月份练习09NISP七月份练习10NISP七
  • Redis系列漏洞总结

    Redis系列漏洞总结 文章目录 Redis系列漏洞总结环境 ubuntu16 04 redis5 0 1 redis下载及安装redis 漏洞利用方式0x01 绝对路径写shell0x02 redis 写入ssh公钥0x03 Redis主
  • 国密浏览器介绍与下载

    国密浏览器介绍与下载 密信浏览器介绍支持操作系统下载地址 奇安信可信浏览器 xff08 国密开发者专版 xff09 介绍支持操作系统下载地址 红莲花安全浏览器介绍支持操作系统下载地址 零信浏览器介绍支持操作系统下载地址 360安全浏览器介绍
  • linux/php一句话图片马及实例

    Ubuntu一句话图片马 准备一张图片tu jpeg phpinfo php和hack php xff1b Phpinfo php文件内容 xff1a hack php文件内容 xff1a 准备一个16进制软件UE UltraEdit li
  • 黑客网络安全扫描工具

    黑客网络安全扫描工具 项目简介1 子域名枚举扫描器或爆破工具2 数据库类漏洞扫描器或爆破工具3 弱口令 弱用户名扫描器或爆破工具4 物联网设备识别工具或扫描器5 反射型或DOM Based XSS扫描器6 企业资产管理或信息泄露搜集工具7
  • MSF之ms17-010永恒之蓝漏洞利用

    MSF之ms17 010永恒之蓝漏洞利用 准备扫描漏洞漏洞攻击 准备 实验准备环境 xff1a 被攻击机 xff1a 虚拟机win7x64位系统 其IP为 xff1a 10 101 2 11 xff08 关闭了防火墙 xff09 攻击机 x
  • linux上安装mysql8.0及常见mysql设置

    1 服务器环境是linux环境 xff0c 使用yum方式安装 yum install mysql server 2 安装完成之后进入目录 etc my cnf 查看文件是否有配置 xff0c 一般都会在 etc my cnf d 文件目录
  • from origin ‘null‘ has been blocked by CORS policy: Cross origin requests are only supported for pro

    Access to script at file C Users dawulei Desktop E9 A1 B9 E7 9B AE E5 9D A6 E5 85 8B E5 A4 A7 E6 88 98 txt htrml js txt
  • 武装服务器(一):云服务器配置aliyundriver-webdav以及使用Aria2和Rclone挂载阿里云盘实现离线下载器

    目录 1 引言2 安装步骤2 1 实验准备2 2 Docker安装2 3 aliyundrive webdav安装2 4 Rclone挂载云盘2 5 配置Aeri2 pro和AriaNg 3 运行4 完成安装 1 引言 云端服务器的硬盘容量
  • 数鸭子问题和角谷定理

    数鸭子问题和角谷定理 一 实验目的 掌握递归程序设计的方法 明确递归的概念 xff0c 通过对问题的分析 xff0c 找出递归关系以及递归出口以对问题进行递归结构设计 xff1b 掌握递归程序转换为非递归程序的方法 二 实验内容 用递归方法
  • ubuntu 18.04 进入恢复(安全)模式修改文件内容

    1 开机时按ESC xff0c 进入BIOS xff08 GRUB menu xff09 上下键选中高级选项 2 选中高级选项按E可以看到ubuntu参数列表 xff08 下面第一张图 xff09 xff1b 接着按ctrl 43 x 或者
  • HTTP各种请求方法的的幂等性和安全性

    幂等性和安全性是http请求方法的特性 比如 get请求方法是具有安全性的 安全性 此次请求不会修改后台 仅指该方法的多次调用不会产生副作用 xff0c 不涉及传统意义上的 安全 xff0c 这里的副作用是指资源状态 即 xff0c 安全的
  • Linux 添加环境变量的两种方法 exprot 临时法 vi /etc/profile永久法

    编写一个shell脚本之后 xff0c 怎么可在任意目录运行改脚本呢 xff1f 为什么别人写的脚本可以直接运行 xff0c 自己写的脚本就会出现 bash XXXXX sh command not found 这样的错误呢 xff1f 1
  • uniapp 安卓/ios 录音授权,录制音频,录音文件上传

    下载依赖插件 官方的app端要权插件 App权限判断和提示 第三方录音组件 录音播放 语音录制voice sound recording 引入依赖 import permision from 34 64 js sdk wa permissi
  • 网络编程:TCP多线程实现多客户端服务器

    TCP多客户端服务器 gt 远程控制 xff08 此篇用多线程实现 xff01 xff09 原理图 xff1a 完整代码如下 xff1a span class token macro property span class token di
  • win10启动ubuntu报错 参考的对象类型不支持尝试的操作

    问题 xff1a 在Windows10系统下启动Ubuntu20 04连接WSL2 xff0c 显示参考的对象类型不支持尝试 解决方案 1 临时有效 通过管理员身份打开Windows PowerShell 打开之后输入以下命令重置Winso

随机推荐