Как использовать повышение:: обяжите в C++ / CLI связывать члена управляемого класса

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

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

blockquote>

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

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})

11
задан Joel Coehoorn 19 November 2008 в 18:15
поделиться

2 ответа

В то время как Ваш ответ работает, он выставляет часть Вашей реализации к миру (Управляемый:: OnSomeEvent). Если Вы не хотите, чтобы люди смогли сгенерировать событие OnChange волей-неволей путем вызова OnSomeEvent (), можно обновить Управляемый класс следующим образом (на основе этого совета):

public delegate void ChangeHandler(void);
typedef void (__stdcall *ChangeCallback)(void);

public ref class Managed
{
public:
    Managed(Native* Nat);
    ~Managed();

    event ChangeHandler^ OnChange;

private:
    void OnSomeEvent(void);
    Native* native;
    Callback* callback;
    GCHandle gch;
};

Managed::Managed(Native* Nat)
 : native(Nat)
{
    callback = new Callback;

    ChangeHandler^ handler = gcnew ChangeHandler( this, &Managed::OnSomeEvent );
    gch = GCHandle::Alloc( handler );
    System::IntPtr ip = Marshal::GetFunctionPointerForDelegate( handler );
    ChangeCallback cbFunc = static_cast<ChangeCallback>( ip.ToPointer() );

    *callback = native->RegisterCallback(boost::bind<void>( cbFunc ) );
}

Managed::~Managed()
{
    native->UnregisterCallback(*callback);
    delete callback;
    if ( gch.IsAllocated )
    {
        gch.Free();
    }
}

void Managed::OnSomeEvent(void)
{
    OnChange();
}

Отметьте альтернативу bind<R>() форма это используется.

10
ответ дан 3 December 2019 в 08:31
поделиться

После поиска с помощью Google еще немного я наконец нашел хорошее сообщение в блоге о том, как сделать это. Код в том сообщении был немного больше, чем мне было нужно, но основной самородок должен был использовать глобальную бесплатную функцию, которая берет аргумент управляемого этот указатель, перенесенный в gcroot <> шаблон. Посмотрите SomeEventProxy (...) в коде ниже для примера. Эта функция затем оборачивается и звонит управляемому участнику, которого я пытался связать. Мое решение появляется ниже для дальнейшего использования.

#include <msclr/marshal.h>

#include <boost/bind.hpp>
#include <boost/signal.hpp>
#include <iostream>

#using <mscorlib.dll>

using namespace System;
using namespace msclr::interop;

typedef boost::signal<void (void)> ChangedSignal;
typedef boost::signal<void (void)>::slot_function_type ChangedSignalCB;
typedef boost::signals::connection  Callback;


class Native
{
public:

    void ChangeIt() 
    {
        changed();
    }

    Callback RegisterCallback(ChangedSignalCB Subscriber)
    {
        return changed.connect(Subscriber);
    }

    void UnregisterCallback(Callback CB)
    {
        changed.disconnect(CB);
    }

private:
    ChangedSignal changed;
};



delegate void ChangeHandler(void);


public ref class Managed
{
public:
    Managed(Native* Nat);
    ~Managed();
    void OnSomeEvent(void);

    event ChangeHandler^ OnChange;

private:
    Native* native;
    Callback* callback;
};


void SomeEventProxy(gcroot<Managed^> This)
{
    This->OnSomeEvent();
}


Managed::Managed(Native* Nat)
 : native(Nat)
{
    native = Nat;
    callback = new Callback;
    *callback = native->RegisterCallback(boost::bind( SomeEventProxy, gcroot<Managed^>(this) ) );
}

Managed::~Managed()
{
    native->UnregisterCallback(*callback);
    delete callback;
}

void Managed::OnSomeEvent(void)
{
    OnChange();
}


void OnChanged(void)
{
    Console::WriteLine("Got it!");
}

int main(array<System::String ^> ^args)
{
    Native* native = new Native;
    Managed^ managed = gcnew Managed(native);

    managed->OnChange += gcnew ChangeHandler(OnChanged);

    native->ChangeIt();

    delete native;
    return 0;
}
4
ответ дан 3 December 2019 в 08:31
поделиться
Другие вопросы по тегам:

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