python - 转换为 tobytes() 时,它会更改 numpy 数组。ValueError:预期的 2D 数组,得到 1D 数组:
问题描述
我正在执行此套接字通信代码以将输入从 server.py(在笔记本电脑上)发送到 client.py(树莓派),在此通信中,我一次从 2d Numpy 数组向客户端发送一行,然后客户端使用 Keras 模型预测输出。通信不是问题,但问题是在套接字通信中发送数据必须以字节为单位,所以每次我发送数据时,我都会将数组更改为字节,并在接收时再次将字节返回到 NumPy 数组。问题是当我尝试更改模型的预测值时,它会更改值。
服务器.py
import socket
import numpy as np
import pandas as pd
import sklearn
from sklearn.preprocessing import MinMaxScaler
import struct
def send_data(connection, data):
data_size = len(data)
data_size_as_4_bytes = struct.pack('>I', data_size)
connection.send(data_size_as_4_bytes)
connection.send(data)
def recv_data(connection, chunk_size=64):
data_size_as_4_bytes = connection.recv(4)
data_size = struct.unpack('>I', data_size_as_4_bytes)[0]
data = b""
size = 0
while size < data_size:
chunk = connection.recv(chunk_size)
print(chunk)
size += len(chunk)
data += chunk
return data
scaler_ti = MinMaxScaler()
test_inputs = []
test_inputs = np.array(test_inputs)
temp_in = pd.read_excel(r'K:\BachelorThesis\Data\TestingData\Mix_Data_inputs.xlsx')
test_inputs = temp_in.to_numpy()
scaler_ti.fit(test_inputs)
normalized_test_inputs = scaler_ti.transform(test_inputs)
HOST = ''
PORT = 62402
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(5)
try:
while True:
print('Waiting for client')
connection, address = s.accept()
print(f"Connection from {address} has been established!")
for row in normalized_test_inputs:
print('send:', row)
data = row.tobytes()
send_data(connection, data)
data = recv_data(connection)
row = np.frombuffer(data)
print(row)
inverse = scaler_ti.inverse_transform(row.reshape(1,8))
print('recv:', inverse)
send_data(connection, 'end'.encode())
connection.close()
except KeyboardInterrupt:
print("Stopped by Ctrl+C")
finally:
s.close()
客户端.py
# author: Bartlomiej "furas" Burek (https://blog.furas.pl)
# date: 2021.07.23
#
# title: receiving back data from the client
# url: https://stackoverflow.com/questions/68499599/receiving-back-data-
from-the-client/68502806#68502806
import socket
import numpy as np
from random import randint
import os
import tensorflow as tf
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.models import load_model
import struct
def send_data(connection, data):
data_size = len(data)
data_size_as_4_bytes = struct.pack('>I', data_size)
connection.send(data_size_as_4_bytes)
connection.send(data)
def recv_data(connection, chunk_size=64):
data_size_as_4_bytes = connection.recv(4)
data_size = struct.unpack('>I', data_size_as_4_bytes)[0]
data = b""
size = 0
while size < data_size:
chunk = connection.recv(chunk_size)
size += len(chunk)
data += chunk
return data
def Predicting(input_data):
input_data = input_data.reshape(1,8)
output_data = modelANN.predict(input_data)
return output_data
modelANN = load_model(os.path.join("K:\BachelorThesis\code
testing\TireForces.LSTM","ANN_model.h5"))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 62402
s.connect((host, port))
while True:
data = recv_data(s)
if data == b'end':
break
input_data = np.frombuffer(data)
print('recv:', input_data)
output_data = Predicting(input_data)
print('send:', output_data)
data = output_data.tobytes()
print(data)
send_data(s, data)
s.close()
server.py 的输出
Waiting for client
Connection from ('192.168.137.1', 52967) has been established!
send: [3.24085967e-04 3.20361343e-04 3.52129031e-04 3.77033700e-04
6.79706856e-01 4.95983138e-01 4.52484158e-04 4.92325891e-01]
b"\x0e\x97/?\xf4\xe68?|\x18)?B\x1c}>\xc5\xd7'?\xf2\xd7\n?=\xe5\x1b?)\x1f\xcb>"
[3.79976874e-04 1.08444638e-07 5.11999896e-05 3.23316134e-06]
Traceback (most recent call last):
File "K:\BachelorThesis\code testing\server.py", line 74, in <module>
inverse = scaler_ti.inverse_transform(row.reshape(1,8))
ValueError: cannot reshape array of size 4 into shape (1,8)
client.py 的输出
recv: [3.24085967e-04 3.20361343e-04 3.52129031e-04 3.77033700e-04
6.79706856e-01 4.95983138e-01 4.52484158e-04 4.92325891e-01]
send: [[0.68589866 0.72227407 0.66052985 0.24717811 0.65563613 0.54235756
0.60896665 0.3967221 ]]
b"\x0e\x97/?\xf4\xe68?|\x18)?B\x1c}>\xc5\xd7'?\xf2\xd7\n?=\xe5\x1b?)\x1f\xcb>"
Traceback (most recent call last):
File "K:\BachelorThesis\code testing\client.py", line 50, in <module>
data = recv_data(s)
File "K:\BachelorThesis\code testing\client.py", line 20, in recv_data
data_size = struct.unpack('>I', data_size_as_4_bytes)[0]
struct.error: unpack requires a buffer of 4 bytes
解决方案
tobytes
只是数组数据缓冲区的字节副本。它不传达任何 dtype 或 shape 信息:
In [31]: x = np.arange(12).reshape((3,4))
In [32]: astr = x.tobytes()
In [33]: astr
Out[33]: b'\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0...\x00\x00\x00'
根据文档,默认负载为 float64:
In [34]: y = np.frombuffer(astr)
In [35]: y
Out[35]:
array([0.0e+000, 4.9e-324, 9.9e-324, 1.5e-323, 2.0e-323, 2.5e-323,
3.0e-323, 3.5e-323, 4.0e-323, 4.4e-323, 4.9e-323, 5.4e-323])
更正dtype
In [36]: y = np.frombuffer(astr, dtype=int)
In [37]: y
Out[37]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
添加形状:
In [38]: y.reshape((3,4))
Out[38]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
推荐阅读
- mysql - 如何解决“ERROR 1215 (HY000): 无法添加外键约束”
- qtranslate - 如何向 QTranslate (ver 6.7.5.1) 应用程序添加翻译服务?
- python - TF/Keras 中输入和输出长度不等的 RNN 层
- java - 如何使用 Spring Boot 登录/注销?
- javascript - 我希望按钮在视频结束前 30 秒显示,无论长度如何
- android - 当应用程序未运行时处理 android 推送通知,如 whatsapp、twitter、facebook、instagram 等
- ios - 我怎样才能更好地转换我的代码
- c++ - C++ getter 和 setter 不传递变量
- mpdf - mPDF,删除编码软件
- sorting - Unix - 根据前两列值对文本文件内容进行排序