Verschillen tussen numpy.random.rand en numpy.random.randn in Python

Wat zijn de verschillen tussen numpy.random.randen numpy.random.randn?

Uit de documentatie weet ik dat het enige verschil tussen beide de probabilistische verdeling is waaruit elk getal is afgeleid, maar de algehele structuur (dimensie) en het gebruikte gegevenstype (float) is hetzelfde. Ik heb hierdoor moeite met het debuggen van een neuraal netwerk.

In het bijzonder probeer ik het neurale netwerk uit het Neural Network and Deep Learning-boek van Michael Nielson opnieuw te implementeren . De originele code vindt u hier. Mijn implementatie was hetzelfde als het origineel; ik heb echter in plaats daarvan gewichten en vooroordelen gedefinieerd en geïnitialiseerd met numpy.random.randin de functie init, in plaats van de numpy.random.randnfunctioneren zoals weergegeven in het origineel.

Mijn code die random.randgebruikt om weights and biaseste initialiseren, werkt echter niet. Het netwerk zal niet leren en de gewichten en vooroordelen zullen niet veranderen.

Wat zijn de verschillen tussen de twee willekeurige functies die deze gekheid veroorzaken?


Antwoord 1, autoriteit 100%

Ten eerste, zoals je kunt zien in de documentatie, genereert numpy.random.randnsteekproeven uit de normale verdeling, terwijl numpy.random.randuit een uniforme verdeling (in de bereik [0,1)).

Ten tweede, waarom werkte de uniforme verdeling niet? De belangrijkste reden is de activeringsfunctie, vooral in het geval dat u de sigmoid-functie gebruikt. De plot van de sigmoid ziet er als volgt uit:

voer hier de afbeeldingsbeschrijving in

Je kunt dus zien dat als je invoer weg is van 0, de helling van de functie vrij snel afneemt en als resultaat krijg je een kleine gradiënt en een kleine gewichtsupdate. En als je veel lagen hebt – die gradiënten worden vele malen vermenigvuldigd in de back-pass, dus zelfs “juiste” gradiënten na vermenigvuldigingen worden klein en hebben geen invloed meer. Dus als je veel gewichten hebt die je input naar die regio’s brengen, is je netwerk nauwelijks te trainen. Daarom is het gebruikelijk om netwerkvariabelen rond de nulwaarde te initialiseren. Dit wordt gedaan om ervoor te zorgen dat u redelijke hellingen (bijna 1) krijgt om uw net te trainen.

Een uniforme verdeling is echter niet iets volledig ongewenst, je moet het bereik alleen kleiner maken en dichter bij nul. Een van de goede praktijken is het gebruik van Xavier-initialisatie. In deze benadering kunt u uw gewichten initialiseren met:

  1. Normale verdeling. Waar het gemiddelde 0 is en var = sqrt(2. / (in + out)), waarbij in – het aantal inputs voor de neuronen is en out – het aantal outputs.

  2. Uniforme verdeling in bereik [-sqrt(6. / (in + out)), +sqrt(6. / (in + out))]


Antwoord 2, autoriteit 45%

  • np.random.randis voor uniforme distributie (in het halfopen interval [0.0, 1.0))
  • np.random.randnis voor Standaard Normale (ook wel Gaussiaanse) distributie (gemiddelde 0 en variantie 1)

Je kunt de verschillen tussen deze twee heel gemakkelijk visueel ontdekken:

import numpy as np
import matplotlib.pyplot as plt
sample_size = 100000
uniform = np.random.rand(sample_size)
normal = np.random.randn(sample_size)
pdf, bins, patches = plt.hist(uniform, bins=20, range=(0, 1), density=True)
plt.title('rand: uniform')
plt.show()
pdf, bins, patches = plt.hist(normal, bins=20, range=(-4, 4), density=True)
plt.title('randn: normal')
plt.show()

Welke producten:

voer hier de afbeeldingsbeschrijving in

en

voer hier de afbeeldingsbeschrijving in


Antwoord 3

1) numpy.random.randvan uniform(binnen bereik [0,1))

2) numpy.random.randngenereert voorbeelden van de normale verdeling

Previous articleWaarom de 6 in relu6?

Other episodes