Todos os desafios
Médio 0 resolvidos 0% de aceitação

Propagação direta em uma camada densa

Calcule as saídas de uma camada de neurônios totalmente conectada com a ativação que você escolher.

O que você vai aprender

  • Calcular uma camada inteira de neurônios de uma vez
  • Aplicar a ativação escolhida a cada saída
  • Organizar os pesos como uma linha por neurônio

Problema

Ver original (inglês)

Uma camada densa é um grupo de neurônios que recebem todos as mesmas entradas. O neurônio j tem seus próprios pesos weights[j] e seu próprio viés biases[j]:

z_j = inputs · weights[j] + biases[j]

Depois, a ativação da camada é aplicada a cada z_j:

  • "linear": retornar z_j sem alteração
  • "relu": max(0, z_j)
  • "sigmoid": 1 / (1 + e^(-z_j))

Implemente dense_forward(inputs, weights, biases, activation).

Entrada

inputs: Os n valores de entrada.

weights: Uma linha por neurônio; cada linha tem n pesos.

biases: Um viés por neurônio.

activation: "linear", "relu" ou "sigmoid".

Saída

Retorne a lista de saídas, uma por neurônio, em ordem.

Restrições

1 ≤ n ≤ 100, 1 ≤ número de neurônios ≤ 100

-10 ≤ cada valor ≤ 10

Exemplos

Exemplo 1
Entrada:
biases = [0.0, -1.0]
inputs = [1.0, 2.0]
weights = [
    [0.5, -1.0],
    [1.5, 0.5]
]
activation = "relu"

Saída esperada:
expected = [0.0, 1.5]
Entrada:
std::vector<double> biases = {0.0, -1.0};
std::vector<double> inputs = {1.0, 2.0};
std::vector<std::vector<double>> weights = {
    {0.5, -1.0},
    {1.5, 0.5}
};
std::string activation = "relu";

Saída esperada:
std::vector<double> expected = {0.0, 1.5};
Entrada:
double[] biases = new double[] {0.0, -1.0};
double[] inputs = new double[] {1.0, 2.0};
double[][] weights = new double[][] {
    new double[] {0.5, -1.0},
    new double[] {1.5, 0.5}
};
string activation = "relu";

Saída esperada:
double[] expected = new double[] {0.0, 1.5};

Explicação

Neurônio 1: 1×0.5 + 2×(-1) + 0 = -1.5, e a ReLU dá 0. Neurônio 2: 1×1.5 + 2×0.5 - 1 = 1.5, que a ReLU mantém. Resultado: [0, 1.5].

Exemplo 2
Entrada:
biases = [1.0, 0.0, -1.5]
inputs = [3.0]
weights = [
    [2.0],
    [-1.0],
    [0.5]
]
activation = "linear"

Saída esperada:
expected = [7.0, -3.0, 0.0]
Entrada:
std::vector<double> biases = {1.0, 0.0, -1.5};
std::vector<double> inputs = {3.0};
std::vector<std::vector<double>> weights = {
    {2.0},
    {-1.0},
    {0.5}
};
std::string activation = "linear";

Saída esperada:
std::vector<double> expected = {7.0, -3.0, 0.0};
Entrada:
double[] biases = new double[] {1.0, 0.0, -1.5};
double[] inputs = new double[] {3.0};
double[][] weights = new double[][] {
    new double[] {2.0},
    new double[] {-1.0},
    new double[] {0.5}
};
string activation = "linear";

Saída esperada:
double[] expected = new double[] {7.0, -3.0, 0.0};

Explicação

Com uma ativação linear, as saídas são simplesmente 3×2 + 1 = 7, 3×(-1) + 0 = -3 e 3×0.5 - 1.5 = 0.

Como abordar

Tente sozinho primeiro e depois abra uma dica de cada vez.

Dica 1

Trate cada neurônio separadamente: cada um tem sua própria linha de pesos e seu próprio bias.

Dica 2

Calcule o produto escalar de cada neurônio com o vetor de entrada, some o bias e depois aplique a ativação escolhida.

Dica 3

Garanta que a ativação seja aplicada depois da etapa linear e preserve a ordem dos neurônios na saída.

Complexidade esperada

tempo O(mn), espaço extra O(m)

Referências

Este desafio foi adaptado para o CodeUtility. Siga o enunciado e as restrições acima.

Aprenda com outros

Soluções da comunidade

Ainda não há soluções publicadas. Resolva este desafio para compartilhar a primeira.