如何将矩阵栈作为TensorFlow输入?数据格式与DNN输入方案问询
嘿,我来帮你搞定这两个问题,先从CSV读取的字符串转数组说起,再聊聊更适合DNN的矩阵数据输入方式:
问题1:将Pandas中的字符串条目转换为浮点型数组
你把多维数组存进CSV的时候,Pandas会自动把它们转成字符串格式,读回来自然就是字符串了,得手动转回去。这里有个简单的方法,用ast.literal_eval把字符串解析成Python列表,再转成Numpy浮点数组:
import ast import numpy as np import pandas as pd # 读取CSV raw_dataset = pd.read_csv('./data.csv') dataset = raw_dataset.copy() # 处理应变(Eps)和应力(Sig)列:字符串转3x3浮点数组 dataset['Eps'] = dataset['Eps'].apply(lambda x: np.array(ast.literal_eval(x), dtype=np.float32)) dataset['Sig'] = dataset['Sig'].apply(lambda x: np.array(ast.literal_eval(x), dtype=np.float32)) # 处理材料参数列(它们存成了类似"[12345]"的字符串,转成单个浮点数) dataset['Shear'] = dataset['Shear'].apply(lambda x: np.array(ast.literal_eval(x), dtype=np.float32).item()) dataset['Lame'] = dataset['Lame'].apply(lambda x: np.array(ast.literal_eval(x), dtype=np.float32).item())
不过要注意,这种方法虽然能解决问题,但CSV本身就不适合存储多维数组,读写效率低还容易出问题,更推荐下面的方法。
问题2:更优的DNN输入矩阵/向量类型数据的方式
直接用Numpy的二进制格式(.npz)存储数据是最佳选择,它能原生保留数组的形状和数值类型,不用做任何字符串转换,读写速度也快很多。下面是完整的优化方案:
步骤1:生成数据并保存为.npz
import numpy as np # 生成样本数据(和你原来的逻辑一致) samples = 10000 eps_non_symmetric = np.random.uniform(low=0, high=0.002, size=(samples, 3, 3)) eps = np.zeros((samples, 3, 3)) for i in range(samples): eps[i, :, :] = np.subtract( np.add(eps_non_symmetric[i, :, :], eps_non_symmetric[i, :, :].T), np.diag(eps_non_symmetric[i, :, :].diagonal())) shear_modulus = np.random.uniform(low=1000, high=300000, size=(samples, 1)) lame_constant = np.random.uniform(low=1000, high=400000, size=(samples, 1)) sig = np.zeros((samples, 3, 3)) for j in range(samples): sig[j, :, :] = 2 * shear_modulus[j] * eps[j, :, :] + lame_constant[j] * np.eye(3) * np.trace(eps[j]) # 直接保存为npz文件,一次性存储所有数组 np.savez('hooke_data.npz', sig=sig, eps=eps, shear=shear_modulus, lame=lame_constant)
步骤2:读取数据并准备模型输入
DNN通常接受一维向量作为输入,所以我们把3x3的应变矩阵展平成9个元素,再和两个材料参数拼接成11维的特征向量;输出则把3x3的应力矩阵展平成9个元素(或者利用应力的对称性,只取6个独立分量,减少模型输出维度):
import numpy as np from sklearn.model_selection import train_test_split # 读取npz文件 data = np.load('hooke_data.npz') sig = data['sig'] eps = data['eps'] shear = data['shear'] lame = data['lame'] # 准备输入特征:应变展平(3x3→9)+ 两个材料参数 → 11维 X = np.concatenate([eps.reshape(samples, 9), shear, lame], axis=1) # 准备输出标签:应力展平(3x3→9),或者取对称分量(6个) y = sig.reshape(samples, 9) # 可选:取对称独立分量(σ11, σ12, σ13, σ22, σ23, σ33) # y = sig[:, [0,0,0,1,1,2], [0,1,2,1,2,2]] # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
步骤3:构建并训练正确的模型
原来的模型输入形状设置错误,现在输入是11维特征,输出是9维(或6维)应力分量:
import tensorflow as tf def build_model(): model = tf.keras.Sequential([ tf.keras.layers.Dense(64, activation='relu', input_shape=(11,)), # 输入维度是11 tf.keras.layers.Dense(64, activation='relu'), tf.keras.layers.Dense(64, activation='relu'), tf.keras.layers.Dense(9) # 输出9个应力分量,换成6如果用对称分量 ]) model.compile(loss='mse', optimizer=tf.optimizers.Adam(learning_rate=0.001), metrics=['mae', 'mse']) return model model = build_model() # 测试预测 example_batch = X_train[:10] example_result = model.predict(example_batch)
这样处理后,不仅解决了字符串转数组的问题,还让数据输入更符合DNN的要求,训练效率和稳定性都会更高。
内容的提问来源于stack exchange,提问作者ahenkes
相关产品推荐
相关产品推荐

