我有一些关于SavedModel
API的问题,我找到的文档留下了很多细节无法解释.
前三个问题是关于什么传递给add_meta_graph_and_variables()
方法的论据tf.saved_model.builder.SavedModelBuilder
,而第四个问题是关于为什么要使用SavedModel
API tf.train.Saver
.
signature_def_map
参数的格式是什么?保存模型时,我通常需要设置此参数吗?
同样,assets_collection
论证的格式是什么?
为什么要保存带有元图的标签列表而不是只给它一个名字(即只附加一个唯一标签)?为什么我要为给定的元图添加多个标签?如果我尝试从pb
某个标签加载metagrpah ,但是那个pb
匹配该标签的多个元图怎么办?
该文档认为,建议用于SavedModel
在自包含文件中保存整个模型(而不仅仅是变量).但tf.train.Saver
除了.meta
文件中的变量外,还会保存图形.那么使用有什么好处SavedModel
?文件说
当您想要保存和加载变量,图形和图形的元数据时 - 基本上,当您想要保存或恢复模型时 - 我们建议使用SavedModel.SavedModel是一种语言中立的,可恢复的,密集的序列化格式.SavedModel支持更高级别的系统和工具来生成,使用和转换TensorFlow模型.
但这个解释很抽象,并没有真正帮助我理解它的优点SavedModel
.什么是具体的例子SavedModel
(相对于tf.train.Saver
)会更好用?
请注意,我的问题与此问题不重复.我不是在问如何保存模型,我问的是关于属性的非常具体的问题SavedModel
,这只是TensorFlow为保存和加载模型提供的多种机制之一.链接问题中的所有答案都没有触及SavedModel
API(再次,它不同于tf.train.Saver
).
注意:可以在下面找到重现我的问题的自包含示例的所有代码.
我有一个tf.keras.models.Model
实例,需要使用低级TensorFlow API编写的训练循环来训练它.
问题:使用基本的标准低级TensorFlow训练循环训练完全相同的tf.keras模型,并使用Keras自己的model.fit()
方法训练一次产生非常不同的结果.我想在我的低级TF训练循环中找出我做错了什么.
该模型是一个简单的图像分类模型,我在Caltech256上训练(链接到下面的tfrecords).
使用低级别的TensorFlow训练循环,训练损失首先会减少,但是经过1000次训练后,失去平稳状态然后再次开始增加:
另一方面,使用普通的Keras训练循环在同一数据集上训练相同的模型,按预期工作:
在我的低级TensorFlow训练循环中我缺少什么?
以下是重现问题的代码(下载带有底部链接的TFRecords):
import tensorflow as tf
from tqdm import trange
import sys
import glob
import os
sess = tf.Session()
tf.keras.backend.set_session(sess)
num_classes = 257
image_size = (224, 224, 3)
# Build a tf.data.Dataset from TFRecords.
tfrecord_directory = 'path/to/tfrecords/directory'
tfrecord_filennames = glob.glob(os.path.join(tfrecord_directory, '*.tfrecord'))
feature_schema = {'image': tf.FixedLenFeature([], tf.string),
'filename': tf.FixedLenFeature([], tf.string),
'label': tf.FixedLenFeature([], tf.int64)}
dataset = tf.data.Dataset.from_tensor_slices(tfrecord_filennames)
dataset = dataset.shuffle(len(tfrecord_filennames)) # Shuffle the TFRecord file names.
dataset = dataset.flat_map(lambda filename: tf.data.TFRecordDataset(filename)) …
Run Code Online (Sandbox Code Playgroud) 我正在运行多个嵌套循环来进行超参数网格搜索.每个嵌套循环遍历超级参数值列表,并且在最内层循环内部,每次使用生成器构建和评估Keras顺序模型.(我没有做任何训练,我只是随机初始化,然后多次评估模型,然后检索平均损失).
我的问题是,在这个过程中,Keras似乎填满了我的GPU内存,所以我最终得到了一个OOM错误.
在评估模型后,是否有人知道如何解决这个问题并释放GPU内存?
在评估之后我根本不再需要模型,我可以在内循环的下一次传递中构建一个新模型之前完全抛弃它.
我正在使用Tensorflow后端.
这是代码,尽管其中大部分与一般问题无关.该模型构建在第四个循环内,
for fsize in fsizes:
Run Code Online (Sandbox Code Playgroud)
我想有关如何构建模型的细节并不重要,但无论如何都是这样的:
model_losses = []
model_names = []
for activation in activations:
for i in range(len(layer_structures)):
for width in layer_widths[i]:
for fsize in fsizes:
model_name = "test_{}_struc-{}_width-{}_fsize-{}".format(activation,i,np.array_str(np.array(width)),fsize)
model_names.append(model_name)
print("Testing new model: ", model_name)
#Structure for this network
structure = layer_structures[i]
row, col, ch = 80, 160, 3 # Input image format
model = Sequential()
model.add(Lambda(lambda x: x/127.5 - 1.,
input_shape=(row, col, ch),
output_shape=(row, col, ch)))
for j in range(len(structure)):
if structure[j] …
Run Code Online (Sandbox Code Playgroud) 我正在训练位于此问题底部的Keras对象检测模型,尽管我认为我的问题既与Keras无关,也不与我要训练的特定模型(SSD)有关,而是与数据方式有关在训练过程中传递给模型。
这是我的问题(请参见下图):我的训练损失总体上在减少,但显示出尖锐的定期峰值:
x轴上的单位不是训练时期,而是数十个训练步骤。峰值每1390个训练步骤发生一次,这恰好是我的训练数据集上一次完整通过的训练步骤数。
尖峰总是在每次经过训练数据集之后始终发生的事实,使我怀疑问题不在于模型本身,而在于训练过程中正在馈送的数据。
我正在使用存储库中提供的批处理生成器在培训期间生成批处理。我检查了生成器的源代码,并且在每次使用之前,它都确实洗牌了训练数据集sklearn.utils.shuffle
。
我感到困惑的原因有两个:
我做了一些测试预测,看看模型是否真的在学习任何东西!随着时间的推移,预测会变得更好,但是当然,该模型的学习速度非常慢,因为这些峰值似乎每1390步就会弄乱梯度。
任何关于这可能得到的提示,我们将不胜感激!我使用上面链接的完全相同的Jupyter笔记本进行培训,我更改的唯一变量是批次大小(从32到16)。除此之外,链接的笔记本包含我正在遵循的准确培训过程。
这是包含模型的存储库的链接:
有两个问题看似相似,但它们不是同一个问题:这里和这里.它们都调用了一种方法GroupBy
,例如count()
或者aggregate()
,我知道它会返回一个方法DataFrame
.我要问的是如何将GroupBy
(类pandas.core.groupby.DataFrameGroupBy
)对象本身转换为DataFrame
.我将在下面说明.
构造DataFrame
如下示例.
data_list = []
for name in ["sasha", "asa"]:
for take in ["one", "two"]:
row = {"name": name, "take": take, "score": numpy.random.rand(), "ping": numpy.random.randint(10, 100)}
data_list.append(row)
data = pandas.DataFrame(data_list)
Run Code Online (Sandbox Code Playgroud)
上面DataFrame
应该如下所示(显然有不同的数字).
name ping score take
0 sasha 72 0.923263 one
1 sasha 14 0.724720 two
2 asa 76 0.774320 one
3 asa 71 0.128721 two
Run Code Online (Sandbox Code Playgroud)
我想要做的是按"name"和"take"( …
我有一个2D Numpy整数数组,如下所示:
a = np.array([[ 3, 0, 2, -1],
[ 1, 255, 1, 2],
[ 0, 3, 2, 2]])
Run Code Online (Sandbox Code Playgroud)
我有一个字典,其中包含整数键和值,我想用它来替换a
新值的值.该字典可能如下所示:
d = {0: 1, 1: 2, 2: 3, 3: 4, -1: 0, 255: 0}
Run Code Online (Sandbox Code Playgroud)
我想用a
键入的值替换匹配的d
值d
.换句话说,d
定义旧(当前)和新(期望)值之间的映射a
.以上玩具示例的结果如下:
a_new = np.array([[ 4, 1, 3, 0],
[ 2, 0, 2, 3],
[ 1, 4, 3, 3]])
Run Code Online (Sandbox Code Playgroud)
实现这一目标的有效方法是什么?
这是一个玩具示例,但实际上数组会很大,它的形状将是例如(1024, 2048)
,字典将具有数十个元素的顺序(在我的情况下为34),而键是整数,它们不是必然都是连续的,它们可以是负数(如上例所示).
我需要在数十万个这样的阵列上执行此替换,因此需要快速.然而,字典是事先已知的并且保持不变,因此渐近地,任何用于修改字典或将其转换为更合适的数据结构的时间都无关紧要.
我正在循环遍历两个嵌套for
循环中的数组条目(在行和列上a
),但必须有一个更好的方法.
如果地图不包含负值(例如,在示例中为-1),我只会在字典中创建一个列表或数组,其中键是数组索引,然后将其用于有效的Numpy花式索引例程.但由于也存在负面价值,因此无效.
我正在尝试访问变体的内容。我不知道里面有什么,但值得庆幸的是,变体确实可以。所以我想我只想问问变体它在什么索引上,然后将该索引用于std::get
它的内容。
但这不能编译:
#include <variant>
int main()
{
std::variant<int, float, char> var { 42.0F };
const std::size_t idx = var.index();
auto res = std::get<idx>(var);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误发生在std::get
呼叫中:
error: no matching function for call to ‘get<idx>(std::variant<int, float, char>&)’
auto res = std::get<idx>(var);
^
In file included from /usr/include/c++/8/variant:37,
from main.cpp:1:
/usr/include/c++/8/utility:216:5: note: candidate: ‘template<long unsigned int _Int, class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)’
get(std::pair<_Tp1, _Tp2>& __in) noexcept
^~~
/usr/include/c++/8/utility:216:5: note: template …
Run Code Online (Sandbox Code Playgroud) 如果我事先不知道它的等级,我如何索引Numpy数组的最后一个轴?
这就是我想要做的:让我们a
成为一个未知等级的Numpy数组.我想要最后k
一个轴的最后一个元素的切片.
如果a
是1D,我想要
b = a[-k:]
Run Code Online (Sandbox Code Playgroud)
如果a
是2D,我想要
b = a[:, -k:]
Run Code Online (Sandbox Code Playgroud)
如果a
是3D,我想要
b = a[:, :, -k:]
Run Code Online (Sandbox Code Playgroud)
等等.
无论等级如何a
(只要等级至少为1),我希望它能够工作.
我想要k
示例中的最后一个元素的事实当然是无关紧要的,关键是我想要在我不知道数组的排名时指定最后一个轴的索引.
注意:用于重现我的问题的独立示例的所有代码都可以在下面找到。
我有一个 tf.keras.models.Model() 实例,希望使用自定义低级 TensorFlow API 训练循环对其进行训练。作为此训练循环的一部分,我需要确保我的自定义训练循环更新来自图层类型(例如tf.keras.layers.BatchNormalization
. 为了实现这一点,我从Francois Chollet 的回答中了解到,我需要model.updates
在每个训练步骤中进行评估。
问题是:当您使用 向模型提供训练数据时,这有效feed_dict
,但当您使用对象时,它不起作用tf.data.Dataset
。
考虑以下抽象示例(您可以在下面找到一个具体示例来重现问题):
model = tf.keras.models.Model(...) # Some tf.keras model
dataset = tf.data.Dataset.from_tensor_slices(...) # Some tf.data.Dataset
iterator = dataset.make_one_shot_iterator()
features, labels = iterator.get_next()
model_output = model(features)
with tf.Session() as sess:
ret = sess.run(model.updates)
Run Code Online (Sandbox Code Playgroud)
这个sess.run()
调用会抛出错误
InvalidArgumentError: You must feed a value for placeholder tensor 'input_1' with dtype float and shape [?,224,224,3]
Run Code Online (Sandbox Code Playgroud)
这个错误显然不应该被提出。我不需要为占位符提供值input_1
,因为我在 a 上调用我的模型tf.data.Dataset
,而不是通过 向占位符提供输入数据 …
我使用 EigeneulerAngles
从旋转矩阵中获取滚动角、俯仰角和偏航角,如下所示:
const Eigen::Vector3f yaw_pitch_roll = rotation.eulerAngles(2, 1, 0);
其中rotation
是 类型的一些有效旋转矩阵Eigen::Matrix3f
。
我观察到的是:如果所有三个角度都接近于零,即如果旋转矩阵接近恒等式,则某些或所有三个所得角度有时会偏离 Pi,即 180 度。
这也可能发生在某些其他旋转中,但到目前为止我只观察到它接近恒等式。
python ×6
keras ×4
tensorflow ×3
c++ ×2
numpy ×2
arrays ×1
c++17 ×1
dictionary ×1
eigen ×1
euler-angles ×1
geometry ×1
grid-search ×1
indexing ×1
pandas ×1
slice ×1
variant ×1