Numpy.NET 获取值
Numpy.NET Getting Values
我正在尝试将 F. Chollet 制作的 Keras 笔记本“转换”为 C#/.NET 应用程序。您可以找到它们 here。我现在专门从事“3.5 - 电影评论”。
问题是,我无法将 NDarray 转换为 C# 数组以使用这些值。我尝试了 this 方法(在 README - Performance Considerations 部分),但我得到随机值或 Python 运行时错误。
using Keras.Datasets;
using Numpy;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace ClassifyingMovieReviews
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Variables
NDarray train_data, train_labels, test_data, test_labels;
NDarray x_train, y_train, x_test, y_test;
public NDarray VectorizeSequences(NDarray sequence, int dimension = 10000)
{
NDarray output = np.zeros((sequence.size, dimension));
int[] value = { 1 };
// this works to extract the first line (as an NDarray!)
NDarray line0 = sequence[0];
// nothing works (of those three)
var raw_data_1 = sequence.GetData<int>();
Console.WriteLine("raw_data_1: " + raw_data_1);
var raw_data_2 = sequence.GetData<float>();
Console.WriteLine("raw_data_2: " + raw_data_2);
var raw_data_3 = sequence.GetData<double>();
Console.WriteLine("raw_data_3: " + raw_data_3);
return output;
}
private void ReadData()
{
// parameters
int top_words = 10000;
// the data, split between train and test sets
((train_data, train_labels), (test_data, test_labels)) = IMDB.LoadData(num_words: top_words);
// Our vectorized training & test data
x_train = VectorizeSequences(train_data);
x_test = VectorizeSequences(test_data);
}
}
}
此外,我的 train_data 和 test_data 似乎是正确的,它们看起来像这样:
train_data = {
[
list([1, 14, 22, ..., 178, 32])
list([1, 194, 1153, ..., 95])
list([1, 14, 47, 8, ..., 2])
...
list([1, 17, 6, ..., 131, 9])
]
}
Numpy.NDarray
编辑:我查看了 Github 源代码以找到解决方案
- GetData<>()
此方法只接受少量类型。我对它们进行了全部测试,但没有任何效果。
我怀疑它不能正常工作,因为我没有多维 NDarray,而是 Python.Runtime 'list' 个对象的 NDarray。
using Keras.Datasets;
using Numpy;
// Variables
NDarray train_data, train_labels, test_data, test_labels;
NDarray x_train, y_train, x_test, y_test;
int top_words = 10000;
// the data, split between train and test sets
((train_data, train_labels), (test_data, test_labels)) = IMDB.LoadData(
num_words: top_words
);
// GetData testing
byte[] byteToCsharp = train_data.GetData<byte>();
short[] shortToCsharp = train_data.GetData<short>();
int[] intToCsharp = train_data.GetData<int>();
long[] longToCsharp = train_data.GetData<long>();
float[] floatToCsharp = train_data.GetData<float>();
double[] doubleToCsharp = train_data.GetData<double>();
bool[] boolToCsharp = train_data.GetData<bool>();
可以找到 GetData
函数签名 here。或者,转到 SciSharp/Numpy.NET 存储库并在搜索栏中搜索“GetData”。
- PadSequences()
这是在 C# 中操作 IMDB 数据集并对序列进行矢量化的答案。请注意,它没有解决我将从 IMDB.LoadData() 获得的 NDarray 转换为 C# 本机数组的问题。
using Keras.Datasets;
using Keras.PreProcessing.sequence;
using Numpy;
// Variables
NDarray train_data, train_labels, test_data, test_labels;
NDarray x_train, y_train, x_test, y_test;
int top_words = 10000;
((x_train, y_train), (x_test, y_test)) = IMDB.LoadData(
num_words: top_words
);
int max_words = 500;
x_train = SequenceUtil.PadSequences(x_train, maxlen: max_words);
x_test = SequenceUtil.PadSequences(x_test, maxlen: max_words);
相反,如果我对函数的理解正确,它会直接调用 Python 中的函数。您可以找到它 here,或在 SciSharp/Keras.NET 存储库的搜索栏中搜索“PadSequences”。
总结
NDarray
上的通用 GetData<T>()
方法 是您想要的。
您只需要:
- 使用正确的数据类型
- 注意 NDarray 的形状
您可以获得例外情况,例如:
System.InvalidOperationException
Python.Runtime.PythonException
如果你弄错了这两位中的任何一位,例如泛型的错误类型或试图从包含本身不是数组的数据的 NDarray(或其维度或切片)中获取数组。您不需要编写自己的代码 ParseManuallyIntoArrayOfInts
例子
using Numpy;
var nDimArray = np.array(new int[] { 1, 2, 3, 4 }).reshape(2, 2);
int[] allElementsFlattened = nDimArray.GetData<int>();
int[] arrayFromDim0 = nDimArray[0].GetData<int>();
int[] arrayFromDim1 = nDimArray[1].GetData<int>();
而尝试获取 错误类型的数据:
var x = nDimArray[1].GetData<object>()
threw an exception of type 'System.InvalidOperationException'
而试图获取 与形状不匹配的数据:
var x = nDimArray[0][0].GetData<int>()
threw an exception of type 'Python.Runtime.PythonException'
字符串化 C# 数组
你的 Console.WriteLine() 不会给你我所期望的 want/expect。您做需要做一点工作来转向,例如将 int[] 转换为字符串(在类型的默认输出之上)。
要获得有用的字符串表示,请尝试这样的操作:
Console.WriteLine($"[{String.Join(", ", nDimArray.GetData<int>()) }]");
哪个会给你例如:
"[1, 2, 3, 4]"
我建议使用断点和监视来查看代码不同步骤中的 NDarray 对象中的内容。
简单的辅助函数
或者,如果您有很多 NDarray 使用推理代码来处理,您还可以创建一个小辅助函数来将核心细节写入调试/控制台,例如:
public static void DisplayNDarray(NDarray nDarray, string name = "")
{
Debug.WriteLine($">> DisplayDetails {name}:");
Debug.WriteLine($"size {nDarray.size} shape {nDarray.shape} dims {nDarray.ndim}");
Debug.WriteLine($"mean {nDarray.mean()} std {nDarray.std()} min {nDarray.min()} max {nDarray.max()}");
}
额外的辅助功能
而对于 ,当您知道数据的基础类型 时,您可以使用另一个简单的助手将数据可视化为字符串
public static void DisplayNDarrayData<TElementType>(NDarray nDarray)
{
Debug.WriteLine($"[{String.Join(", ", nDarray.GetData<TElementType>())}]");
}
被称为:
DisplayNDarrayData<int>(nDimArray);
我正在尝试将 F. Chollet 制作的 Keras 笔记本“转换”为 C#/.NET 应用程序。您可以找到它们 here。我现在专门从事“3.5 - 电影评论”。
问题是,我无法将 NDarray 转换为 C# 数组以使用这些值。我尝试了 this 方法(在 README - Performance Considerations 部分),但我得到随机值或 Python 运行时错误。
using Keras.Datasets;
using Numpy;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace ClassifyingMovieReviews
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Variables
NDarray train_data, train_labels, test_data, test_labels;
NDarray x_train, y_train, x_test, y_test;
public NDarray VectorizeSequences(NDarray sequence, int dimension = 10000)
{
NDarray output = np.zeros((sequence.size, dimension));
int[] value = { 1 };
// this works to extract the first line (as an NDarray!)
NDarray line0 = sequence[0];
// nothing works (of those three)
var raw_data_1 = sequence.GetData<int>();
Console.WriteLine("raw_data_1: " + raw_data_1);
var raw_data_2 = sequence.GetData<float>();
Console.WriteLine("raw_data_2: " + raw_data_2);
var raw_data_3 = sequence.GetData<double>();
Console.WriteLine("raw_data_3: " + raw_data_3);
return output;
}
private void ReadData()
{
// parameters
int top_words = 10000;
// the data, split between train and test sets
((train_data, train_labels), (test_data, test_labels)) = IMDB.LoadData(num_words: top_words);
// Our vectorized training & test data
x_train = VectorizeSequences(train_data);
x_test = VectorizeSequences(test_data);
}
}
}
此外,我的 train_data 和 test_data 似乎是正确的,它们看起来像这样:
train_data = {
[
list([1, 14, 22, ..., 178, 32])
list([1, 194, 1153, ..., 95])
list([1, 14, 47, 8, ..., 2])
...
list([1, 17, 6, ..., 131, 9])
]
}
Numpy.NDarray
编辑:我查看了 Github 源代码以找到解决方案
- GetData<>()
此方法只接受少量类型。我对它们进行了全部测试,但没有任何效果。
我怀疑它不能正常工作,因为我没有多维 NDarray,而是 Python.Runtime 'list' 个对象的 NDarray。
using Keras.Datasets;
using Numpy;
// Variables
NDarray train_data, train_labels, test_data, test_labels;
NDarray x_train, y_train, x_test, y_test;
int top_words = 10000;
// the data, split between train and test sets
((train_data, train_labels), (test_data, test_labels)) = IMDB.LoadData(
num_words: top_words
);
// GetData testing
byte[] byteToCsharp = train_data.GetData<byte>();
short[] shortToCsharp = train_data.GetData<short>();
int[] intToCsharp = train_data.GetData<int>();
long[] longToCsharp = train_data.GetData<long>();
float[] floatToCsharp = train_data.GetData<float>();
double[] doubleToCsharp = train_data.GetData<double>();
bool[] boolToCsharp = train_data.GetData<bool>();
可以找到 GetData
函数签名 here。或者,转到 SciSharp/Numpy.NET 存储库并在搜索栏中搜索“GetData”。
- PadSequences()
这是在 C# 中操作 IMDB 数据集并对序列进行矢量化的答案。请注意,它没有解决我将从 IMDB.LoadData() 获得的 NDarray 转换为 C# 本机数组的问题。
using Keras.Datasets;
using Keras.PreProcessing.sequence;
using Numpy;
// Variables
NDarray train_data, train_labels, test_data, test_labels;
NDarray x_train, y_train, x_test, y_test;
int top_words = 10000;
((x_train, y_train), (x_test, y_test)) = IMDB.LoadData(
num_words: top_words
);
int max_words = 500;
x_train = SequenceUtil.PadSequences(x_train, maxlen: max_words);
x_test = SequenceUtil.PadSequences(x_test, maxlen: max_words);
相反,如果我对函数的理解正确,它会直接调用 Python 中的函数。您可以找到它 here,或在 SciSharp/Keras.NET 存储库的搜索栏中搜索“PadSequences”。
总结
NDarray
上的通用 GetData<T>()
方法 是您想要的。
您只需要:
- 使用正确的数据类型
- 注意 NDarray 的形状
您可以获得例外情况,例如:
System.InvalidOperationException
Python.Runtime.PythonException
如果你弄错了这两位中的任何一位,例如泛型的错误类型或试图从包含本身不是数组的数据的 NDarray(或其维度或切片)中获取数组。您不需要编写自己的代码 ParseManuallyIntoArrayOfInts
例子
using Numpy;
var nDimArray = np.array(new int[] { 1, 2, 3, 4 }).reshape(2, 2);
int[] allElementsFlattened = nDimArray.GetData<int>();
int[] arrayFromDim0 = nDimArray[0].GetData<int>();
int[] arrayFromDim1 = nDimArray[1].GetData<int>();
而尝试获取 错误类型的数据:
var x = nDimArray[1].GetData<object>()
threw an exception of type 'System.InvalidOperationException'
而试图获取 与形状不匹配的数据:
var x = nDimArray[0][0].GetData<int>()
threw an exception of type 'Python.Runtime.PythonException'
字符串化 C# 数组
你的 Console.WriteLine() 不会给你我所期望的 want/expect。您做需要做一点工作来转向,例如将 int[] 转换为字符串(在类型的默认输出之上)。
要获得有用的字符串表示,请尝试这样的操作:
Console.WriteLine($"[{String.Join(", ", nDimArray.GetData<int>()) }]");
哪个会给你例如:
"[1, 2, 3, 4]"
我建议使用断点和监视来查看代码不同步骤中的 NDarray 对象中的内容。
简单的辅助函数
或者,如果您有很多 NDarray 使用推理代码来处理,您还可以创建一个小辅助函数来将核心细节写入调试/控制台,例如:
public static void DisplayNDarray(NDarray nDarray, string name = "")
{
Debug.WriteLine($">> DisplayDetails {name}:");
Debug.WriteLine($"size {nDarray.size} shape {nDarray.shape} dims {nDarray.ndim}");
Debug.WriteLine($"mean {nDarray.mean()} std {nDarray.std()} min {nDarray.min()} max {nDarray.max()}");
}
额外的辅助功能
而对于 ,当您知道数据的基础类型 时,您可以使用另一个简单的助手将数据可视化为字符串
public static void DisplayNDarrayData<TElementType>(NDarray nDarray)
{
Debug.WriteLine($"[{String.Join(", ", nDarray.GetData<TElementType>())}]");
}
被称为:
DisplayNDarrayData<int>(nDimArray);