tenorsflow ValueError: Градиенты не указаны для любой переменной, проверьте график на наличие операций, которые не поддерживают градиенты

template
struct range_t {
  It b, e;
  It begin() const { return b; }
  It end() const { return e; }
};
template
range_t range( It s, It f ) { return {std::move(s), std::move(f)}; }

это минимальный тип для поддержки циклов for(:) в произвольных диапазонах.

Далее, что я называю индексированием iteroid:

template
struct indexing_iteroid {
  using self=indexing_iteroid;
  V value;

  // * just returns a copy of value
  V operator*() const& { return value; }
  V operator*()&&{ return std::move(value); }

  // ++ forwards to value:
  self& operator++() {
    ++value;
    return *this;
  }
  self operator++(int) {
    auto r = *this;
    ++*this;
    return r;
  }

  // == compares values:
  friend bool operator==(self const& lhs, self const& rhs) {
    return lhs.value == rhs.value;
  }
  friend bool operator!=(self const& lhs, self const& rhs) {
    return lhs.value != rhs.value;
  }
};

, если вы хотите вы можете распространить это на полноценный итератор ввода; Для этого, кроме того, для этого требуются резервные контейнеры.

Но этот итерайд достаточно хорош для петель for(:), которые не указаны в терминах категорий итераторов, а скорее конкретных операций.

template
range_t< indexing_iterator > index_over_range( range_t r ) {
  return {{r.begin()}, {r.end()}};
}

это принимает диапазон и создает диапазон над итераторами в нем.

for (auto it : index_over_range( range( infoMap.begin(), infoMap.end() ) ) )
{
}

теперь это for(:) цикл, который посещает каждый итератор в infoMap , а не каждый элемент из infoMap.

Мы можем немного почистить это с большим количеством шаблонов

namespace adl {
  namespace it_details {
    using std::begin; using std::end;
    template
    auto adl_begin( X&& x )
    -> decltype( begin( std::forward(x) ) )
    { return begin( std::forward(x) ); }
    template
    auto adl_end( X&& x )
    -> decltype( end( std::forward(x) ) )
    { return end( std::forward(x) ); }
  }
  template
  auto begin( X&& x )
  -> decltype( it_details::adl_begin( std::forward(x) ) )
  { return it_details::adl_begin( std::forward(x) ); }
  template
  auto end( X&& x )
  -> decltype( it_details::adl_end( std::forward(x) ) )
  { return it_details::adl_end( std::forward(x) ); }
}

, это дает adl::begin( x ) ( и adl::end( x )), который вызывает begin в x в контексте, где std::begin доступен, но так же зависит от поиска по запросу begin. Это почти идеально соответствует тому, как петли for(:) находят свои итераторы начала и конца.

template
auto iterators_of( C& c )
-> decltype( index_over_range( range( adl::begin(c), adl::end(c) ) ) )
{ return index_over_range( range( adl::begin(c), adl::end(c) ) ); }

теперь iterators_of(someMap) возвращает диапазон всех итераторов в someMap:

for (auto it : iterators_of( infoMap ) )
{
}

, и у нас есть хороший, чистый эффективный синтаксис.

Как в стороне, indexing_iteroid можно также использовать для создания итерации счетчика (так что для цикла для 0, 1, 2, 3), например:

using counting_iteroid = indexing_iteroid;
auto zero_to_ten = range( counting_iteroid{0}, counting_iteroid{11} );
for (auto x : zero_to_ten) {
   std::cout << x << "\n";
}

выше, вероятно, имеет некоторые опечатки.

Существует категория типов, для которой indexing_iteroid может быть обернута; как целые числа, так и итераторы передают эту концепцию. Вы можете улучшить indexing_iteroid, чтобы быть ближе к случайному доступу, но из-за недостатков в том, как стандартизована концепция итератора произвольного доступа, он не позволяет вам достичь более высокой категории итераторов ввода итератора. 'Rangesv3 может исправить это.

0
задан keineahnung2345 19 January 2019 в 10:14
поделиться

1 ответ

У вас есть эта проблема, потому что аргументы, которые вы передали в tf.nn.softmax_cross_entropy_with_logits не то, что он хочет. Из документа tf.nn.softmax_cross_entropy_with_logits :

Типичный вариант использования - иметь логиты и метки формы [batch_size, num_classes], но поддерживаются более высокие измерения, с аргумент dim, определяющий размерность класса.

Таким образом, вы должны закодировать вашу цель в горячем виде перед подачей ее в нейронную сеть. Ниже приводится исполняемый код:

from sklearn import datasets
import random
import tensorflow as tf
import numpy as np
from sklearn.preprocessing import OneHotEncoder

wine=datasets.load_wine()
wine_data = wine.data
onehotencoder = OneHotEncoder()
wine_target = onehotencoder.fit_transform(wine.target[...,np.newaxis]).toarray()

def generate_batch(batch_size,wine):
    batch_x=[]
    batch_y=[]
    for _ in range(batch_size):
        index=random.randint(0,177)
        batch_y.append(wine_target[index])
        batch_x.append(wine_data[index])
    return batch_x,batch_y

def inference(x):
    with tf.variable_scope('layer1'):
        weight1 = tf.get_variable('weight', [13, 7], initializer=tf.truncated_normal_initializer(stddev=0.1))
        bias1 = tf.get_variable('bias', [7], initializer=tf.constant_initializer(0.1))
        layer1 = tf.nn.relu(tf.matmul(x, weight1) + bias1)
    weight2 =tf.get_variable('weight', [7, 3], initializer=tf.truncated_normal_initializer(stddev=0.1))
    bias2 = tf.get_variable('bias', [3], initializer=tf.constant_initializer(0.1))
    logit = tf.matmul(layer1, weight2) + bias2
    return logit

x=tf.placeholder(tf.float32,[None,13])
y_=tf.placeholder(tf.float32,[None, 3])
y=inference(x)

cross_entropy=tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y)
cross_entropy_mean=tf.reduce_mean(cross_entropy)

train_step=tf.train.GradientDescentOptimizer(0.001).minimize(cross_entropy_mean)
correct_prediction = tf.equal(y ,y_)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for i in range(2000):
        data,target=generate_batch(20,wine)
        sess.run(train_step,feed_dict={x:data,y_:target})
0
ответ дан keineahnung2345 19 January 2019 в 10:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: