Posted on

Azure App Service: Risolvere la saturazione dei socket (SNAT) tramite Auto-Heal

 

Vai sulla tua App Service nel portale Azure

Seleziona nel menu a sinistra “Diagnostica e risoluzione dei problemi”

Seleziona “Diagnostic Tools”

Seleziona “Auto-Heal”

Come impostare la regola di “Riparazione”

Una volta aperta la schermata di Auto-Heal, ti consiglio di configurarla così per gestire il problema dei socket saturati:

  1. Define Conditions: Scegli Request Count.

    • Esempio: 2000 richieste in un intervallo di 10 minuti (o un valore che reputi alto per il tuo traffico normale).

  2. Configure Actions: Seleziona Recycle.

  3. Override Title: Salva la regola.

In questo modo, Azure monitora il traffico e, se vede un picco anomalo (che spesso precede il blocco dei socket), riavvia il processo prima che l’app diventi irraggiungibile.

Posted on

Blazor WebAssembly with JWT Authentication on Web Api Server

Dopo aver configurato l’autenticazione (vedi), il passo logico successivo è far sì che la tua app Blazor parli con il tuo Web API server in modo sicuro.

Riassunto della “Stretta di Mano”

  1. Auth0: Rilascia il “passaporto” (Token) a Blazor.

  2. Blazor: Prende il passaporto e lo mette in una busta (Header HTTP) e lo manda al Server.

  3. Server (JWT): Dice “Controllo il passaporto: è firmato da Auth0 ed è valido. Prego, puoi passare!”

 

Configurazione su Auth0.com

Single Page Applications

Le Regular Web Applications (come Blazor Server) e le Single Page Applications (come Blazor WASM) usano due modi completamente diversi di gestire la sicurezza:

  • Blazor Server (Regular Web App): Il “segreto” risiede sul server. Può gestire Client Secret e scambi di token protetti “dietro le quinte”.

  • Blazor WASM (SPA): Il codice gira nel browser dell’utente. Non può custodire segreti (perché chiunque farebbe F12 e li vedrebbe). Usa il flusso PKCE (senza secret).

Nel nostro caso è fondamentale che la nostra applicazione su Auth0 sia una Single Page Application altrimenti Auth0 non rilascia l’access-token. In definitiva :

  • ID Token: È la tua carta d’identità. Serve a Blazor per sapere chi sei (nome, email). L’audience (aud) è giustamente il ClientId. Non può essere usato per chiamare le API.

  • Access Token: È il tuo “pass” per il server. Deve avere come audience (aud) l’URL della tua API. Se questo manca, il server API vede la tua carta d’identità ma dice: “Non mi interessa chi sei, mi serve il pass per questa risorsa”.

Assicurati che la tua Auth0 app sia una single page appllication.

Scope nell’API di Auth0

Assicurati che lo scope che chiedi nel codice sia registrato nell’API:

  1. Dashboard Auth0 -> APIs -> [Tua API] -> Scheda Permissions.

  2. Verifica che esista esattamente la riga leggi:miecose, altrimenti inseriscila

 

WEB API Server

Il vostro server che espone api non protette (fino ad ora) è probabilmente un un classico progetto ASP.NET Core Web API (basato su Controller). È la struttura più solida e comune per gestire API aziendali.

Per prima cosa, dobbiamo installare il componente che gestisce i token JWT. Apri il terminale in Visual Studio (o il Gestore Pacchetti NuGet) e installa:

Microsoft.AspNetCore.Authentication.JwtBearer

Se il tuo progetto è in .NET 8 e i pacchetti esistenti sono alla versione 8.0.7, installare un pacchetto alla versione 10.0.0 (che appartiene a una versione di .NET non ancora rilasciata o in preview) creerebbe quasi certamente dei conflitti di dipendenze e bug in fase di compilazione.

Mantenere tutto sulla v8.x.x garantisce che tutti i componenti parlino la stessa lingua.

Configurazione in Program.cs

Apri il file Program.cs. Dobbiamo aggiungere il servizio di autenticazione e dire alle API di usare Auth0. Cerca il punto in cui vengono registrati i servizi (prima di var app = builder.Build();) e incolla questo:

using Microsoft.AspNetCore.Authentication.JwtBearer;

#region Auth0
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = $"https://{builder.Configuration["Auth0:Domain"]}/";
options.Audience = builder.Configuration["Auth0:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true
};
});
#endregion

 

Poi, scendi verso il basso dove viene configurata la “pipeline” (dopo var app = builder.Build();) e aggiungi queste due righe esattamente in questo ordine (devono stare tra UseRouting e MapControllers):

app.UseRouting(); // Aggiungilo se non c'è, aiuta a gestire meglio i percorsi

app.UseAuthentication(); // Deve venire PRIMA di UseAuthorization

app.UseAuthorization();

app.MapControllers();

CORS

Dato che il tuo Web Server (API) e la tua App Blazor girano probabilmente su porte o domini diversi, il server deve esplicitamente permettere a Blazor di parlargli.

Nel Program.cs del Server API, assicurati di avere il CORS configurato:

// Nel Server API
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins("https://localhost:XXXX") // L'URL della tua Blazor WASM
.AllowAnyHeader()
.AllowAnyMethod();
});
});

// ... dopo builder.Build()
app.UseCors();

Oppure puoi usare una policy “aperta” (se la sicurezza del tuo scenario lo permette):

//TUTTI
builder.Services.AddCors(options =>
{
options.AddPolicy("OpenPolicy", policy =>
{
policy.AllowAnyOrigin() // Accetta chiamate da chiunque (anche dalla Blazor WASM)
.AllowAnyHeader()
.AllowAnyMethod();
});
});

Nota sulla sicurezza: Con l’autenticazione Auth0 che abbiamo appena messo, anche se il CORS è “aperto”, nessuno potrà leggere i dati protetti senza un token valido. Quindi sei comunque al sicuro!

Configura le credenziali in appsettings.json

Apri il file appsettings.json nel progetto API e aggiungi i dati che trovi nella dashboard di Auth0 (sotto la voce API):

{
  "Auth0":
       {
          "Domain": "[IL-TUO-TENANT].auth0.com",
          "Authority": "https://[IL-TUO-TENANT].auth0.com",
          "Audience": "https://api.iltuoservizio.com"
      }
}

Controller di prova

Crea un controller per provare le chiamate che richiedono autorizzazione (es. AuthController.cs)

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
// Questa API è protetta!
[HttpGet("test-privato")]
[Authorize]
public IActionResult GetPrivato()
{
return Ok(new { Messaggio = "Se vedi questo, l'autenticazione funziona!" });
}

// Questa API è pubblica (come le tue attuali)
[HttpGet("test-pubblico")]
public IActionResult GetPubblico()
{
return Ok(new { Messaggio = "Questa è un'API libera." });
}
}

Come verificare se funziona?

Se provi a chiamare l’API direttamente da Swagger dopo queste modifiche, dovresti ricevere un errore 401 Unauthorized. (Le altre continueranno a rispondere 200 OK come sempre.) È il segno che la protezione è attiva!

Modifiche al client Blazor WebAssembly

Dobbiamo istruire Blazor a usare un “MessageHandler” speciale. Questo componente intercetta le chiamate in uscita e aggiunge automaticamente il token Authorization: Bearer <TOKEN>.

Configurazione in Program.cs

Rispetto alla versione precedente dobbiamo forzare il flusso PKCE nella configurazione Auth0, ed aggiungere il client http per le chiamate al nostro server :

using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using TestBlazorWasmArticolo;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

// =========================================================
// >>> REGISTRAZIONI DI BASE (Devono venire prima di AddOidcAuthentication) <<<
// =========================================================
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<SignOutSessionStateManager>();
// =========================================================

// =========================================================
// >>> Parte cruciale per l'autenticazione Auth0/OIDC <<<
// =========================================================
builder.Services.AddOidcAuthentication(options =>
{
// Impostazione dell'Audience (CRUCIALE per chiamare le API)
// L'Audience deve essere passato come parametro aggiuntivo OIDC
options.ProviderOptions.AdditionalProviderParameters.Add(
"audience",
builder.Configuration["Auth0:Audience"]!
);

// Modifica o aggiungi questo per assegnare esplicitamente l'Authority
options.ProviderOptions.Authority = builder.Configuration["Auth0:Authority"]!;

// Assegna il ClientId
options.ProviderOptions.ClientId = builder.Configuration["Auth0:ClientId"]!;

// 2. Forza il flusso PKCE
options.ProviderOptions.ResponseType = "code";

// Aggiungi tutti gli scope richiesti, inclusi quelli personalizzati:
options.ProviderOptions.DefaultScopes.Add("openid");
options.ProviderOptions.DefaultScopes.Add("profile");
options.ProviderOptions.DefaultScopes.Add("email");
options.ProviderOptions.DefaultScopes.Add("address");
options.ProviderOptions.DefaultScopes.Add("phone");
options.ProviderOptions.DefaultScopes.Add("leggi:miecose"); // <--- Scope API

// FORZA LA RICHIESTA DI CONSENSO
//options.ProviderOptions.AdditionalProviderParameters.Add("prompt", "consent");
});


// =========================================================

#region API
string urlservice = "https://" + builder.Configuration["TestWebservice:Address"] + "/";
builder.Services.AddScoped<AuthorizationMessageHandler>();

// Registra l'HttpClient usando la factory
builder.Services.AddHttpClient("ApiGateway", client =>
{
client.BaseAddress = new Uri(urlservice);
})
.AddHttpMessageHandler(sp =>
{
// Configuriamo l'handler al volo
return sp.GetRequiredService<AuthorizationMessageHandler>()
.ConfigureHandler(
authorizedUrls: new[] { urlservice },
scopes: new[] { "leggi:miecose" }
);
});
#endregion

//Client httpclient per chimatae locali (weather)
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();

ResponseType = “code”: Questo dice a Blazor e Auth0 di usare il flusso PKCE, che è lo standard moderno per le Single Page Application e risolve molti problemi di “blocco” durante il ritorno dal redirect.

Creazione della Pagina Protetta

Ora creiamo una nuova pagina Razor, ad esempio FetchDati.razor. Questa pagina dovrà essere accessibile solo agli utenti loggati.

@page "/fetch-dati"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Microsoft.AspNetCore.Components.Authorization
@attribute [Authorize]
@inject IHttpClientFactory ClientFactory
@inject IAccessTokenProvider TokenProvider
@inject NavigationManager Navigation

<PageTitle>Dati Protetti</PageTitle>

<AuthorizeView>
<Authorized>
<h3>Dati dal Server</h3>
@if (messaggioDalServer == null)
{
<p>Caricamento dati in corso...</p>
}
else
{
<div class="alert alert-success">@messaggioDalServer</div>
}
<h3>Test Api Gateway</h3>
<button class="btn btn-success" @onclick="CaricaDatiConToken">Carica Dati con Token</button>
<p>@messaggioDalServer</p>
</Authorized>
<Authorizing>
<p>Controllo autorizzazione...</p>
</Authorizing>
</AuthorizeView>

@code {
private string? messaggioDalServer = "ciao";

protected override async Task OnInitializedAsync()
{
try
{
var client = ClientFactory.CreateClient("ApiGateway");
// Proviamo prima una chiamata semplicissima per vedere se il problema è il Token
var response = await client.GetAsync("api/Auth/test-privato");

if (response.IsSuccessStatusCode)
{
messaggioDalServer = await response.Content.ReadAsStringAsync();
}
else
{
messaggioDalServer = $"Errore Server: {response.StatusCode}";
}
}
catch (AccessTokenNotAvailableException ex)
{
// Se il token fallisce, reindirizza
ex.Redirect();
}
catch (Exception ex)
{
// Se c'è un errore di rete o altro, lo scriviamo ma non blocchiamo l'app
messaggioDalServer = $"Errore tecnico: {ex.Message}";
Console.WriteLine(ex.ToString());
}
}

private async Task CaricaDatiConToken()
{
// 1. Chiediamo il token manualmente
var tokenResult = await TokenProvider.RequestAccessToken();

if (tokenResult.TryGetToken(out var token))
{
try
{
var client = ClientFactory.CreateClient("ApiGateway");

// 2. Aggiungiamo il token manualmente all'header
client.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token.Value);

var response = await client.GetAsync("api/auth/test-privato");
messaggioDalServer = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
messaggioDalServer = $"Errore chiamata: {ex.Message}";
}
}
else
{
// Questo ti dirà PERCHÉ fallisce (es. "consent_required", "invalid_scope")
if (tokenResult.Status == AccessTokenResultStatus.RequiresRedirect)
{
messaggioDalServer = "Errore: È necessario un redirect per il consenso.";
Console.WriteLine("tokenResult.InteractiveRequestUrl: " + tokenResult.InteractiveRequestUrl);
// Navigation.NavigateTo(tokenResult.InteractiveRequestUrl); // Scommenta se vuoi forzare il consenso
}
else
{
messaggioDalServer = $"Errore GetToken: {tokenResult.Status}";
}
}

}

public class RispostaApi { public string Messaggio { get; set; } = ""; }
}

Cosa fare adesso?

Il “motore” è montato e sincronizzato. Ora non resta che accenderlo:

  1. Avvia il Web Server API (assicurati che sia su HTTPS).

  2. Avvia la Blazor WASM App.

  3. Naviga sulla pagina fetcdati.razor.

Posted on

Blazor WebAssembly with Auth0 Authentication

Focus su Blazor WebAssembly (WASM)

Blazor WebAssembly è l’opzione più adatta per creare applicazioni client per il consumo di API.

Punti Chiave

  1. C# nel Browser: L’intero runtime .NET e la tua applicazione sono scaricati dal browser come file WebAssembly. Il codice C# viene eseguito direttamente nel browser in un sandbox.

  2. Architettura SPA: Blazor WASM crea applicazioni Single Page Application (SPA), il che significa che l’applicazione viene caricata una volta e le successive interazioni utente aggiornano dinamicamente solo le parti necessarie della pagina, offrendo un’esperienza utente fluida.

  3. Componenti Razor: Le interfacce utente sono costruite utilizzando i componenti Razor (.razor), che combinano markup HTML con logica C# (usando la direttiva @code).

Scrivere un’app in Blazor significa usare una tecnologia Microsoft (C#) che però poggia su una base totalmente aperta e universale (WebAssembly). Questo garantisce che la tua app funzionerà su qualsiasi dispositivo moderno, senza dipendere da plugin proprietari

Focus su Auth0

  • Auth0 è un Identity Provider che usa il protocollo OIDC (OpenID Connect).

  • Blazor WASM è un client OIDC nativo e Microsoft fornisce le librerie Microsoft.AspNetCore.Components.WebAssembly.Authentication per gestirlo.

  • L’applicazione Blazor reindirizza l’utente alla pagina di login Auth0 (Universal Login), riceve l’Access Token e lo memorizza.

Progetto Blazor WebAssembly

Creazione del Progetto in Visual Studio

  • Apri Visual Studio e crea un Nuovo Progetto.

  • Cerca e seleziona il template “Blazor WebAssembly App” (assicurati che non sia “Blazor Server App”).

  • Nella finestra di configurazione, per quanto riguarda  l’Autenticazione, scegli “Nessuna”

✅ Riepilogo delle Tue Scelte (Consigliate)

Opzione Stato (Check) Note
Applicazione Web Progressiva (PWA) Deselezionato Non necessario ora, aumenta la complessità.
Non usare istruzioni di primo livello Deselezionato Usa il codice moderno e conciso di .NET.
Configura per HTTPS Selezionato Essenziale. La tua app deve usare HTTPS per l’autenticazione con Auth0 (e per chiamare le API in produzione).
Include sample pages Selezionato Utile per avere un’architettura di base già pronta (layout, menu) e per testare velocemente l’autenticazione.

Configurazione su Auth0.com

Applicazione

Nel portale Auth0 crea una nuova applicazione di tipo “Single Page Application“.

Nella applicazione , nella tab settings :

  • prendi nota di : Domain e ClientID.
  • Seleziona “Cross-Origin Authentication”

API

Nella sezione API , Clicca su + Create API. Devi compilare questi campi:

  • Name (Nome): Un nome descrittivo (es. “Mio Servizio Dati API”).

  • Identifier (Identificativo): Questo è l’Audience!

Il Campo Identifier (Audience)

L’Identificativo (Audience) deve essere un URI (Uniform Resource Identifier) e di solito ha questo formato:

Esempio Audience: https://api.iltuoservizio.com

Importante: Non deve per forza essere un URL funzionante, ma deve essere un URI univoco.

Configurazione di Auth0 e delle Dipendenze

Pacchetti

Per autenticare un’applicazione Blazor WebAssembly con Auth0, devi utilizzare il supporto integrato di Microsoft per l’autenticazione OIDC (OpenID Connect), che è il protocollo utilizzato da Auth0. Con Nuget

  • installa il pacchetto Microsoft.Authentication.WebAssembly.Msal
  • installa il pacchetto Microsoft.AspNetCore.Components.WebAssembly.Authentication. Attenzione: installare la versione 8.0.1
  • installa il pacchetto Microsoft.Extensions.Http

Configurazione Applicazione

Nelle applicazioni .NET (inclusi i client Blazor WASM), il file appsettings.json è lo standard per archiviare le configurazioni, come: le Credenziali di Autenticazione: (Il Domain e il Client ID di Auth0). Blazor WebAssembly è progettato per leggere le impostazioni da questo file. Crea il file appsettings.json nella directory wwwroot per mantenere le configurazioni separate dal codice (il che è una best practice).

{
  "Auth0":
       {
          "Domain": "[IL-TUO-TENANT].auth0.com",
          "Authority": "https://[IL-TUO-TENANT].auth0.com",
          "ClientId": "[IL-TUO-CLIENT-ID-AUTH0.COM]",
          "Audience": "https://api.iltuoservizio.com"
      },
  "TestWebservice:
     {
       "Address": "localhost:7003"
     }
}

File Applicazione

Program.cs
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

// =========================================================
// >>> REGISTRAZIONI DI BASE (Devono venire prima di AddOidcAuthentication) <<<
// =========================================================
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<SignOutSessionStateManager>();
// =========================================================

// =========================================================
// >>> Parte cruciale per l'autenticazione Auth0/OIDC <<<
// =========================================================
builder.Services.AddOidcAuthentication(options =>
{
// Impostazione dell'Audience (CRUCIALE per chiamare le API)
// L'Audience deve essere passato come parametro aggiuntivo OIDC
options.ProviderOptions.AdditionalProviderParameters.Add(
"audience",
builder.Configuration["Auth0:Audience"]!
);

// Modifica o aggiungi questo per assegnare esplicitamente l'Authority
options.ProviderOptions.Authority = builder.Configuration["Auth0:Authority"]!;

// Assegna il ClientId
options.ProviderOptions.ClientId = builder.Configuration["Auth0:ClientId"]!;

// 3. Configurazione degli Scope
// Sostituiamo gli Scope predefiniti con la tua lista completa.
options.ProviderOptions.DefaultScopes.Clear(); // Rimuovi gli scope predefiniti

// Aggiungi tutti gli scope richiesti, inclusi quelli personalizzati:
options.ProviderOptions.DefaultScopes.Add("openid");
options.ProviderOptions.DefaultScopes.Add("profile");
options.ProviderOptions.DefaultScopes.Add("email");
options.ProviderOptions.DefaultScopes.Add("address");
options.ProviderOptions.DefaultScopes.Add("phone");
options.ProviderOptions.DefaultScopes.Add("read:appointments"); // <--- Scope API
});

// =========================================================

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();
MainLayout.razor

Per mostrare lo stato di login, devi usare il componente Blazor integrato CascadingAuthenticationState nel file di layout principale.

Nel file Layout/MainLayout.razor, assicurati che il contenuto sia racchiuso in questo

@using Microsoft.AspNetCore.Components.Authorization
@inherits LayoutComponentBase

<div class="page">
<div class="sidebar">
<NavMenu />
</div>

<CascadingAuthenticationState>
<main>
<div class="top-row px-4">
<LoginDisplay /> 
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>

<article class="content px-4">

@Body

</article>
</main>
</CascadingAuthenticationState>
</div>
LoginDisplay.razor

Crea la cartella Shared ed in essa il componente LoginDisplay.razor.

@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager

<AuthorizeView>
<Authorized>
Ciao, @context.User.Identity?.Name!
<button class="nav-link btn btn-link" @onclick="BeginSignOut">Log out</button>
</Authorized>
<NotAuthorized>
<a href="authentication/login">Log in</a>
</NotAuthorized>
</AuthorizeView>

@code {
[CascadingParameter]
private Task<AuthenticationState>? AuthenticationState { get; set; }

private async Task BeginSignOut()
{
// Reindirizza l'utente al flusso di Logout di Auth0 (tramite il gestore Blazor)
await SignOutManager.SetSignOutState();
Navigation.NavigateTo("authentication/logout");
}
}

Importante. Per usare questo componente è necessario aggiungere a _Imports.razor il collegamento alla cartella Shared.

Script di Autenticazione (index.html)

Devi semplicemente aggiungere il tag <script> mancante nel tuo index.html nella sezione <body>, prima del tag che carica Blazor (_framework/blazor.webassembly.js).

Aggiungi questa riga:

<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
Authentication.razor

Crea il componente Pages/Authentication.razor

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

<RemoteAuthenticatorView Action="@Action" />

@code {
[Parameter]
public string? Action { get; set; }

// NOTA BENE: Non è necessario dichiarare RouteData
// in questo componente specifico se usi solo l'Action
}

Configurazione Auth0.com (seconda parte)

Lanciando l’app vedrete che la scritta Login in alto compare ma compare con u lieve ritardo. Se spingo login , scrive “Checking login state…” , poi, dopo alcuni secondi, vieni reindirizzato su una pagina si Auth0.com con errore “Callback URL mismatch.The provided redirect_uri is not in the list of allowed callback URLs.”

Trovate la vostra applicazione :

  • alla voce “Allowed Callback Urls” aggiungete   : https://localhost:7004/authentication/login-callback
  • alla voce “Allowed Logout Urls” aggiungete : https://localhost:7004/authentication/logout-callback

Riprovate. Dovreste avere implementato Login e Logout

Posted on

L’amministratore globale non ha accesso ad una sottoscrizione di Azure

L’amministratore globale non può usare la sottoscrizione Azure

In quanto amministratore globale di un tenant Microsoft avete accesso a tutte le risorse del tenant. Se acquistate una nuova sottoscrizione di Azure e carcate di creare una nuova risorsa all’interno della sottoscrizione, vi viene comunicato l’errore : “Le autorizzazioni non sono sufficienti per creare gruppi di risorse nella sottoscrizione”.

Problema

Il problema è che anche se siete amministratori del tenant, non siete a default anche proprietari della sottoscrizione.

Soluzione

Entrate nel portale di Azure e selezionate la sottoscrizione. Selezionate nel menu di sinistra “Controllo accesso (IAM)”. In alto spingete “Aggiungi ” -> “Aggiungi una assegnazione di Ruolo”.

Cercate il ruolo “Proprietario” che troverete nella tab “Ruoli di amministratore con privilegi”. Spingete in basso “Avanti”, selezionate l’utente e concludete la procedura.

Potrebbe essere necessario attendere 24 ore prima di poter usare la sottoscrizione Azure come proprietario, anche se il nuovo ruolo risulta già sull’utente

Posted on

Intelligenza Artificiale : Reti Profonde, Algoritmo di Backpropagation, i Grandi Modelli Linguistici (LLM):

Reti Profonde

Le reti neurali profonde (Deep Neural Networks, DNN) sono reti neurali con un elevato numero di strati nascosti (tipicamente più di due o tre). La profondità della rete permette di apprendere gerarchie di caratteristiche sempre più complesse e astratte dai dati di input. Ad esempio, in una rete profonda per il riconoscimento di immagini, i primi strati potrebbero apprendere a riconoscere bordi e angoli, gli strati intermedi forme e texture, e gli strati più profondi oggetti interi.

L’avvento di tecniche di addestramento più efficaci, l’aumento della potenza computazionale (grazie alle GPU) e la disponibilità di grandi quantità di dati hanno reso possibile l’addestramento di reti profonde con milioni o addirittura miliardi di parametri, portando a progressi significativi in molti campi dell’IA. Architetture profonde specializzate come le CNN per la visione artificiale e le RNN (e le loro varianti come LSTM e GRU) per l’elaborazione di sequenze hanno dimostrato una notevole capacità di apprendimento.

Apprendimento: Cenni sull’Algoritmo di Backpropagation

L’apprendimento in una rete neurale artificiale consiste nell’aggiustare i pesi sinaptici e i bias dei neuroni in modo da minimizzare l’errore tra l’output prodotto dalla rete e l’output desiderato (presente nei dati di training). L’algoritmo di apprendimento più comunemente utilizzato per addestrare reti neurali feedforward profonde è la backpropagation (retropropagazione del gradiente).

L’algoritmo di backpropagation funziona in due fasi principali (acanti e indietro):

  • Forward Pass (Avanti): L’input viene propagato attraverso la rete neurale, strato dopo strato, fino a produrre un output (la predizione della rete).

  • Calcolo dell’Errore: Confronti questo output con l’output corretto (l’etichetta vera per quell’input nel set di training). La differenza tra i due è l’errore della rete per quell’esempio specifico.

  • Calcolo del Gradiente: A partire da questo errore, si calcola il gradiente. Il gradiente indica quanto velocemente l’errore cambierebbe se venisse fatta una piccola modifica a ciascun peso e bias nella rete. In altre parole, ci dice in quale direzione dovremmo muovere i pesi e i bias per diminuire l’errore.L’errore viene propagato all’indietro attraverso la rete, calcolando il gradiente dell’errore rispetto a ciascun peso e bias. Questo gradiente indica la direzione in cui i pesi e i bias devono essere modificati per ridurre l’errore.

Questo processo viene ripetuto per molte epoche (passaggi sull’intero dataset di training) fino a quando la rete non converge a uno stato in cui l’errore è sufficientemente basso.

I Grandi Modelli Linguistici (LLM)

I Grandi Modelli Linguistici (Large Language Models, LLM) rappresentano un’evoluzione straordinaria nel campo dell’elaborazione del linguaggio naturale (NLP). Basati su architetture di reti neurali profonde, in particolare la Transformer, gli LLM sono addestrati su enormi quantità di dati testuali (spesso miliardi di parole). Questa scala massiva di dati e parametri permette loro di apprendere rappresentazioni ricche e contestuali del linguaggio, consentendo loro di svolgere una vasta gamma di compiti linguistici con una coerenza e una fluidità sorprendenti.

Le capacità degli LLM includono:

  • Generazione di testo: Scrivere articoli, email, storie, codice e altro ancora.
  • Comprensione del linguaggio naturale: Rispondere a domande, riassumere testi, tradurre lingue.
  • Completamento di frasi e paragrafi.
  • Dialogo e conversazione.
  • Ragionamento linguistico di base.

Esempi notevoli di LLM includono GPT-3, GPT-4, LaMDA, PaLM e molti altri. La loro capacità di generare testo che spesso è indistinguibile da quello umano ha suscitato grande interesse e anche preoccupazioni riguardo al loro potenziale misuse.


INDICE

Posted on

Intelligenza Artificiale : Reti Neurali Artificiali

Le Reti Neurali Artificiali (RNA) rappresentano uno dei pilastri fondamentali e di maggiore successo dell’Intelligenza Artificiale contemporanea. Ispirate vagamente alla struttura e al funzionamento del cervello biologico, le RNA sono modelli computazionali capaci di apprendere rappresentazioni complesse dai dati, ottenendo risultati straordinari in una vasta gamma di applicazioni, dal riconoscimento di immagini e voce all’elaborazione del linguaggio naturale e alla robotica.

Il Neurone Artificiale: Il Modello del Percettrone

L’unità di base di una rete neurale artificiale è il neurone artificiale, spesso chiamato anche nodo o unità. Il modello più semplice di neurone artificiale è il percettrone, introdotto da Frank Rosenblatt negli anni ’50. Il suo compito è prendere una serie di input, elaborarli in modo molto basilare, e produrre un singolo output (una decisione).

Un percettrone riceve uno o più segnali di input (x1​,x2​,…,xn​), a ciascuno dei quali è associato un peso sinaptico (w1​,w2​,…,wn​) che ne determina l’importanza. Gli input pesati vengono sommati, e alla somma viene aggiunto un bias (b), un valore costante che permette di spostare la soglia di attivazione. Il risultato di questa somma ponderata viene poi passato attraverso una funzione di attivazione che determina l’output del neurone (y).

Come Funziona? Gli Ingredienti Chiave:

1.Input (Caratteristiche): Il percettrone riceve uno o più input. Questi input rappresentano le caratteristiche (o features) dell’elemento che stiamo cercando di classificare. Pensa alle caratteristiche come alle diverse “domande” che fai sull’oggetto per decidere a quale categoria appartiene.

    • Esempio: Se stiamo cercando di decidere se un’email è spam o no, gli input potrebbero essere: la frequenza di certe parole (“gratis”, “offerta”), la lunghezza dell’email, se il mittente è sconosciuto, ecc. Ogni input ha un valore numerico.

2. Pesi: Ad ogni input è associato un peso. Questi pesi rappresentano l’importanza di ciascun input nella decisione finale del percettrone.

      • Esempio: Se la presenza della parola “gratis” è un forte indizio di spam, il peso associato a quell’input sarà elevato. Se la lunghezza dell’email è meno importante, il suo peso sarà più basso. I pesi possono essere positivi o negativi.

3. Somma Ponderata: Il percettrone calcola la somma ponderata degli input. Questo significa che ogni input viene moltiplicato per il suo peso corrispondente, e poi tutti questi prodotti vengono sommati insieme.

    • Matematicamente: somma = (input_1 * peso_1) + (input_2 * peso_2) + ... + (input_n * peso_n)

4. Bias (Soglia): Al risultato della somma ponderata viene aggiunto un valore costante chiamato bias (o soglia). Il bias permette al percettrone di essere attivato anche quando tutti gli input sono zero o molto piccoli, oppure di dover superare una certa “inerzia” prima di attivarsi.

    • Matematicamente: somma_con_bias = somma + bias

5. Funzione di Attivazione: Il risultato finale (somma_con_bias) viene passato attraverso una funzione di attivazione. Questa funzione decide l’output del percettrone basandosi sul valore che riceve. Una funzione di attivazione semplice per un percettrone è la funzione a gradino (step function):

    • SE somma_con_bias è maggiore di una certa soglia (spesso 0), l’output è 1 (o “attivato”, o appartenente a una certa classe).
    • ALTRIMENTI (se somma_con_bias è minore o uguale alla soglia), l’output è 0 (o “non attivato”, o appartenente all’altra classe).

In Sintesi: Prendere una Decisione Binaria

Il percettrone è fondamentalmente un classificatore binario: decide se un input appartiene a una di due classi (ad esempio, spam/non spam, gatto/non gatto, vero/falso). Lo fa valutando quanto “pesano” le diverse caratteristiche dell’input e confrontando la loro combinazione con una soglia.

Il percettrone è in grado di apprendere a classificare pattern lineari modificando i suoi pesi e il bias attraverso un algoritmo di apprendimento.

Reti Neurali (Artificiali): Architettura Generale

Una rete neurale artificiale è costituita da un insieme interconnesso di neuroni artificiali organizzati tipicamente in strati. L’architettura più comune è quella delle reti neurali feedforward (o a propagazione in avanti), in cui l’informazione fluisce in una sola direzione, dagli strati di input agli strati nascosti (uno o più) fino allo strato di output.

  • Strato di Input: Riceve i dati di input grezzi (ad esempio, i pixel di un’immagine, le parole di una frase).
  • Strati Nascosti: Interposti tra l’input e l’output, questi strati eseguono trasformazioni complesse sui dati di input, apprendendo rappresentazioni intermedie utili per il compito specifico. Il numero e la dimensione degli strati nascosti (il numero di neuroni in ciascuno strato) determinano la capacità del modello di apprendere funzioni complesse.
  • Strato di Output: Produce il risultato finale del modello (ad esempio, la classe di un’immagine, la previsione di un valore numerico, la probabilità di una sequenza di parole).

Le connessioni tra i neuroni di strati adiacenti sono caratterizzate dai pesi sinaptici, che vengono appresi durante la fase di training.

connessioni ricorrenti

L’architettura di una rete neurale può variare significativamente a seconda del tipo di problema da risolvere, includendo anche connessioni ricorrenti. Le connessioni ricorrenti si riferiscono a connessioni che creano dei cicli all’interno della rete. Invece di avere un flusso di informazioni strettamente direzionale da uno strato all’altro (come nelle reti feedforward), in una rete con connessioni ricorrenti, l’output di un neurone (o di un intero strato) può essere re-immesso come input allo stesso neurone o a neuroni in strati precedenti.


INDICE

Posted on

Intelligenza Artificiale : Apprendimento Supervisionato, Non Supervisionato e Reinforcement Learning

Il Machine Learning può essere ampiamente suddiviso in tre tipi di apprendimento principali, basati sulla natura dei dati di training disponibili:

  • Apprendimento Supervisionato: L’algoritmo apprende da un dataset etichettato, in cui ogni istanza di input è associata a un’etichetta o un valore di output corretto. L’obiettivo è imparare una funzione che possa mappare correttamente nuovi input alle loro corrispondenti etichette o valori. La classificazione e la regressione sono i compiti principali dell’apprendimento supervisionato. Esempi di algoritmi includono alberi decisionali, support vector machine e reti neurali.

 

  • Apprendimento Non Supervisionato: L’algoritmo apprende da un dataset non etichettato, cercando di scoprire strutture nascoste, pattern o relazioni intrinseche nei dati. L’obiettivo non è predire un output specifico, ma piuttosto comprendere l’organizzazione dei dati. Compiti tipici includono il clustering (raggruppare istanze simili), la riduzione della dimensionalità (trovare rappresentazioni più compatte dei dati) e la scoperta di regole associative. Esempi di algoritmi includono k-means, analisi delle componenti principali (PCA) e algoritmi di clustering gerarchico.

 

  • Reinforcement Learning (Apprendimento per Rinforzo): Un agente apprende come comportarsi in un ambiente attraverso l’interazione. Riceve feedback sotto forma di ricompense o punizioni per le sue azioni. L’obiettivo dell’agente è imparare una politica (una strategia di comportamento) che massimizzi la ricompensa cumulativa nel tempo. Questo paradigma è particolarmente adatto per problemi di controllo, robotica e giochi. Esempi di algoritmi includono Q-learning e Deep Q-Networks (DQN).

Tecniche di Apprendimento:

Esiste un vasto arsenale di tecniche di apprendimento all’interno del Machine Learning. Ecco alcuni esempi significativi:

Alberi Decisionali

Sono modelli di apprendimento supervisionato che rappresentano una serie di decisioni sequenziali a forma di albero. Ogni nodo interno rappresenta un test su un attributo, ogni ramo rappresenta un possibile risultato del test e ogni foglia rappresenta una decisione o una previsione. Sono intuitivi, facili da interpretare e possono gestire sia dati categorici che numerici. Algoritmi popolari includono CART e C4.5.

 

Support Vector Machine (SVM)

Sono potenti algoritmi di apprendimento supervisionato utilizzati principalmente per la classificazione, ma anche per la regressione. L’idea chiave è trovare un iperpiano nello spazio delle caratteristiche che separi al meglio le istanze di diverse classi, massimizzando il margine tra le classi. Le SVM sono efficaci in spazi ad alta dimensionalità e possono utilizzare funzioni per gestire dati non linearmente separabili.

Immagina di avere due gruppi di oggetti (ad esempio, mele e pere) sparsi su un tavolo. Il tuo obiettivo è tracciare una linea (o una superficie, in 3D o più dimensioni) che separi al meglio le mele dalle pere.

  • L’obiettivo della SVM è trovare questa “linea di separazione” (iperpiano) nel modo più intelligente possibile. “Intelligente” significa che la linea non solo deve separare correttamente le mele dalle pere che hai già visto (i dati di allenamento), ma deve anche lasciare un “margine” il più ampio possibile tra la linea e gli oggetti più vicini di ciascun gruppo.

  • Pensa a questo margine come a una zona “cuscinetto” intorno alla linea. Più ampio è questo cuscinetto, più è probabile che la linea sia una buona separatrice anche per nuove mele e pere che non hai ancora visto (migliore generalizzazione).

  • I “Support Vectors” sono le mele e le pere più vicine a questa linea di separazione. Sono questi punti “di supporto” che aiutano a definire la posizione e l’orientamento ottimale della linea.

  • E se i gruppi non sono facilmente separabili con una linea retta? La SVM ha un trucco! Può usare delle funzioni speciali (chiamate “kernel”) per trasformare i dati in uno spazio di dimensioni più alte, dove potrebbe diventare più facile trovare una linea di separazione. Immagina di lanciare le mele e le pere in aria: in 3D potrebbe essere più facile trovare un piano che le separi rispetto a una semplice linea sul tavolo 2D.

In breve, la SVM cerca di trovare la migliore “frontiera” per separare diverse categorie di dati, massimizzando lo spazio vuoto intorno a questa frontiera per rendere la classificazione più robusta per dati futuri.

 

Reti Bayesiane (o Modelli Grafici Probabilistici)

Sono modelli probabilistici che rappresentano le dipendenze tra un insieme di variabili casuali. Permettono di modellare l’incertezza e di effettuare deduzioni probabilistiche. Sono utilizzate in una varietà di applicazioni, tra cui la diagnosi medica e il riconoscimento del linguaggi.

  • Le Reti Bayesiane sono un modo per rappresentare e ragionare sulle relazioni probabilistiche tra diverse cose (variabili). Invece di dire “SE A ALLORA B” in modo rigido (come nei sistemi simbolici), le Reti Bayesiane dicono cose come “SE A è vero, ALLORA B è più probabile“.

  • Una Rete Bayesiana è un disegno (un grafo) dove i cerchi (nodi) rappresentano le variabili (ad esempio, “pioggia”, “strada bagnata”, “incidente”) e le frecce tra i cerchi rappresentano le dipendenze probabilistiche. Una freccia da “pioggia” a “strada bagnata” significa che la probabilità che la strada sia bagnata dipende (in parte) dalla probabilità che piova.

  • Ogni nodo nella rete ha associata una tabella di probabilità che quantifica queste dipendenze. Ad esempio, la tabella per “strada bagnata” potrebbe dire: “Se piove (probabilità alta), allora la probabilità che la strada sia bagnata è molto alta. Se non piove (probabilità bassa), allora la probabilità che la strada sia bagnata è bassa (ma non zero, potrebbe esserci un irrigatore)”.

  • Il bello delle Reti Bayesiane è che, una volta che hai costruito la rete e le tabelle di probabilità, puoi fare inferenze. Se osservi che la strada è bagnata, puoi usare la rete per aggiornare la tua credenza (probabilità) sul fatto che abbia piovuto. Questo processo si chiama inferenza (deduzione) Bayesiana.

In breve, le Reti Bayesiane sono un modo per modellare come diverse cose sono probabilmente correlate tra loro e come l’osservazione di una cosa può influenzare la nostra credenza sulla probabilità di altre cose. Sono utili quando c’è incertezza e vogliamo ragionare in termini di probabilità.

Algoritmi Genetici

Sono algoritmi di ottimizzazione ispirati al processo di evoluzione biologica. Mantengono una popolazione di potenziali soluzioni (individui) e utilizzano operatori genetici come la selezione, la mutazione per evolvere la popolazione verso soluzioni migliori nel corso delle generazioni. Sono particolarmente utili per problemi di ottimizzazione complessi con spazi di ricerca vasti.


Conclusione:

Il Machine Learning ha rivoluzionato il campo dell’Intelligenza Artificiale, offrendo un approccio potente e flessibile per affrontare problemi complessi attraverso l’apprendimento dai dati. Superando i limiti intrinseci dell’approccio simbolico, il ML si basa su principi statistici e su una varietà di tecniche per risolvere problemi di classificazione, regressione e pianificazione. La continua evoluzione degli algoritmi di apprendimento supervisionato, non supervisionato e per rinforzo sta aprendo nuove frontiere e applicazioni per l’IA, con un impatto sempre maggiore sulla nostra vita quotidiana.


INDICE

Posted on

Intelligenza Artificiale : I Problemi della Classificazione, Regressione e Pianificazione

Il Machine Learning affronta una vasta gamma di problemi, ma tre categorie principali spiccano per la loro importanza e frequenza:

  • Classificazione: L’obiettivo è assegnare ad un input (un dato in ingresso come un immagine) a una delle diverse categorie predefinite (è un gatto). Esempi includono il riconoscimento di immagini (gatto vs. cane), la diagnosi medica (malato vs. sano) e il filtraggio di email (spam vs. non spam). Gli algoritmi di classificazione imparano un modello dai dati etichettati per predire la classe dei nuovi input dati in pasto al programma.

 

  • Regressione: L’obiettivo è predire un valore numerico dato un input in ingresso. Esempi includono la previsione dei prezzi delle case, la stima della temperatura futura e la predizione delle vendite di un prodotto. Gli algoritmi di regressione imparano una funzione che mappa l’input a un valore numerico.

                          Es: Stima della Temperatura Futura:

            • Un’istanza di input è un singolo momento nel tempo per il quale vogliamo prevedere la temperatura.
            • Le caratteristiche potrebbero essere: la temperatura attuale, l’umidità, la pressione atmosferica, la velocità e la direzione del vento, la data e l’ora, ecc.
            • L’obiettivo della regressione è predire un valore numerico continuo, che è la temperatura stimata (ad esempio, 28.5 gradi Celsius).
  • Pianificazione (nel contesto del Reinforcement Learning): Nel Reinforcement Learning, la pianificazione si riferisce al processo attraverso il quale un agente (il sistema di intelligenza artificiale) utilizza un modello dell’ambiente per decidere quali azioni intraprendere. A differenza dell’apprendimento diretto dall’esperienza reale (senza un modello), la pianificazione permette all’agente di simulare diverse sequenze di azioni e prevedere le loro conseguenze prima di agire effettivamente nell’ambiente

                        Esempi di Pianificazione in RL:

          • Gioco degli Scacchi o Go: Un agente di RL con un modello delle regole del gioco può pianificare diverse mosse in anticipo, simulando le risposte dell’avversario e valutando il risultato di ogni sequenza di mosse per scegliere la migliore.
          • Robotica: Un robot che deve navigare in un ambiente può avere un modello del suo ambiente (una mappa). Può pianificare un percorso verso l’obiettivo simulando diversi movimenti e scegliendo quello che evita ostacoli e minimizza il tempo o l’energia spesa.
          • Gestione di Risorse: Un sistema che gestisce l’energia di una casa intelligente può avere un modello del consumo energetico previsto e dei prezzi dell’elettricità. Può pianificare l’utilizzo degli elettrodomestici per minimizzare i costi.

Questi problemi fondamentali sono affrontati utilizzando una varietà di algoritmi e tecniche di apprendimento.


INDICE

Posted on

Intelligenza Artificiale : Limiti dell’Approccio Simbolico, Approccio Subsimbolico, Pattern ed Apprendimento Statistico

Limiti dell’Approccio Simbolico

l’approccio simbolico all’IA presenta limiti significativi, in particolare quando si tratta di affrontare problemi complessi e ambigui del mondo reale:

  • Difficoltà nell’acquisizione della conoscenza: Il “collo di bottiglia dell’acquisizione della conoscenza” rimane una sfida importante. Formalizzare la conoscenza esperta in un insieme completo e coerente di regole può essere arduo, dispendioso in termini di tempo e soggetto a errori.

 

  • Fragilità e mancanza di robustezza: I sistemi simbolici tendono ad essere fragili e possono fallire in modo catastrofico di fronte a input leggermente diversi o imprevisti, per i quali non sono state esplicitamente programmate regole.

 

  • Difficoltà nella gestione dell’incertezza e della variabilità: Il mondo reale è intrinsecamente incerto e variabile. La logica formale e le regole rigide faticano a gestire la vaghezza, la probabilità e le eccezioni.

 

  • Scalabilità limitata: Per problemi complessi con un gran numero di variabili e interazioni, il numero di regole necessarie può crescere esponenzialmente, rendendo il sistema difficile da progettare, mantenere e scalare.

 

  • Incapacità di apprendere da soli: I sistemi simbolici sono statici e non hanno la capacità intrinseca di apprendere e adattarsi a nuovi dati o a cambiamenti nell’ambiente senza un intervento umano diretto.

Questi limiti hanno spianato la strada all’emergere e alla rapida crescita del Machine Learning, un approccio più orientato ai dati e all’apprendimento automatico.

Approccio Subsimbolico ed Apprendimento Statistico

In contrasto con l’approccio simbolico, il Machine Learning si basa su un approccio subsimbolico e sull’apprendimento statistico. Invece di manipolare simboli espliciti, gli algoritmi di ML operano su dati grezzi, estraendo pattern e relazioni statistiche nascoste.

  • Rappresentazioni distribuite: Le informazioni non sono codificate in simboli discreti, ma in pattern di attivazione distribuiti su un insieme di unità (come i neuroni in una rete neurale). Questi pattern possono catturare sfumature e somiglianze in modo più flessibile rispetto alle rigide categorie simboliche.
  • Inferenza statistica: Il ML utilizza tecniche statistiche per analizzare i dati, quantificare l’incertezza e fare previsioni o prendere decisioni basate sulla probabilità.
  • Apprendimento guidato dai dati: L’elemento centrale è l’apprendimento attraverso l’esperienza, rappresentata da grandi quantità di dati. Gli algoritmi modificano i propri parametri interni per migliorare le proprie prestazioni su un determinato compito, basandosi sui feedback ricevuti dai dati di training.

Questo approccio si è dimostrato particolarmente efficace in domini complessi come il riconoscimento di immagini e vocale, l’elaborazione del linguaggio naturale e la scoperta di pattern in grandi dataset, dove l’approccio simbolico faticava a fornire soluzioni robuste e scalabili.

Pattern

Nel contesto del Machine Learning (ML) e dell’analisi dei dati, un pattern è una regolarità significativa, una struttura ricorrente, una relazione non ovvia o una tendenza che si manifesta all’interno di un insieme di dati. I pattern sono ciò che gli algoritmi di ML cercano di identificare per poter fare previsioni, classificare elementi, raggruppare dati simili o scoprire nuove informazioni.

In termini più semplici, un pattern è qualcosa che si ripete o che è coerente nei dati e che fornisce un’informazione utile.

Esempi di Pattern in Diversi Contesti:

  • Riconoscimento di Immagini:

    • Un pattern potrebbe essere una specifica combinazione di pixel che forma il bordo di un oggetto, la trama di una superficie o la forma di un occhio in un’immagine.
    • Un algoritmo di riconoscimento facciale cerca pattern unici nella disposizione di occhi, naso, bocca, ecc.

 

  • Elaborazione del Linguaggio Naturale:

    • Un pattern potrebbe essere la frequente co-occorrenza di determinate parole in una frase che indica una relazione semantica (ad esempio, “burro” e “pane” compaiono spesso insieme).
    • Pattern grammaticali specifici possono indicare il sentimento di una frase (ad esempio, l’uso frequente di aggettivi negativi).

 

  • Serie Temporali (Previsioni Azionarie, Meteo):

    • Un pattern potrebbe essere una tendenza stagionale in cui le vendite di un prodotto aumentano ogni dicembre.
    • Un pattern meteorologico potrebbe essere una sequenza specifica di cambiamenti di pressione che precede una tempesta.
  • Diagnosi Medica:

    • Un pattern potrebbe essere una specifica combinazione di sintomi e risultati di test di laboratorio che è fortemente correlata a una particolare malattia.

Caratteristiche dei Pattern che il Machine Learning cerca:

  • Non ovvi: I pattern interessanti non sono ovvi o facilmente individuabili con una semplice ispezione dei dati.
  • Significativi: I pattern dovrebbero fornire un’informazione utile per il compito specifico (previsione, classificazione, ecc.).
  • Ricorrenti: I pattern tendono a ripetersi all’interno del dataset, indicando una sottostante regolarità.
  • Generalizzabili (idealmente): Un pattern è generalizzabile se la relazione o la struttura che rappresenta è fondamentale e sottostante ai dati, piuttosto che una coincidenza o un artefatto specifico del set di training.
      • Esempio di Pattern Generalizzabile: Se impariamo che i funghi velenosi hanno spesso un certo tipo di anello sotto il cappello e un colore brillante, questo pattern (se vero nella realtà) ci aiuterà a identificare funghi velenosi anche se non abbiamo mai visto prima quella specifica specie.

      • Esempio di Pattern Non Generalizzabile (Overfitting): Se nel nostro set di training di foto di gatti Siamese, tutti i gatti hanno un collare rosso, il modello potrebbe imparare che “avere un collare rosso” è un pattern associato ai gatti. Tuttavia, questo pattern non si generalizzerà ad altri gatti Siamese senza collare o ad altre razze di gatti con o senza collare. Il modello ha appreso una correlazione spuria presente solo nel training set.

In sostanza, l’obiettivo del Machine Learning è di fornire ai computer la capacità di “imparare” dai dati, e questo apprendimento avviene attraverso l’identificazione e l’utilizzo di pattern significativi presenti in quei dati.


INDICE

Posted on

Intelligenza Artificiale : Sistemi Simbolici e Conoscenza Esperta

Un approccio storico e ancora rilevante nell’IA è quello dei sistemi simbolici, che si basano sulla rappresentazione esplicita della conoscenza attraverso simboli, regole logiche e strutture dati. I sistemi esperti sono un esempio di questo approccio. Essi mirano a codificare la conoscenza di esperti umani in un dominio specifico (ad esempio, la diagnosi medica o la configurazione di sistemi complessi) in una base di conoscenza e a utilizzare regole di deduzione per risolvere problemi e fornire consulenza.

I punti di forza dei sistemi simbolici includono:

  • Trasparenza e interpretabilità: Le decisioni prese da un sistema simbolico possono essere spiegate tracciando la catena di deduzioni logiche.
  • Capacità di ragionamento logico: Sono particolarmente adatti per compiti che richiedono deduzione e pianificazione basata su regole.
  • Facilità di aggiornamento e manutenzione della conoscenza: La conoscenza può essere aggiunta o modificata in modo relativamente diretto.

Tuttavia, i sistemi simbolici presentano anche delle limitazioni:

  • Difficoltà nell’acquisizione della conoscenza: Estrarre e formalizzare la conoscenza esperta da esseri umani può essere un processo complesso e dispendioso in termini di tempo (il cosiddetto “collo di bottiglia dell’acquisizione della conoscenza”).
  • Fragilità: Le prestazioni del sistema possono degradare significativamente al di fuori del dominio di conoscenza specifico o in presenza di input imprevisti.
  • Difficoltà nella gestione dell’incertezza e della conoscenza vaga: La logica formale può avere difficoltà a rappresentare e ragionare con informazioni incerte o imprecise.

Nonostante queste limitazioni, i sistemi simbolici e la rappresentazione della conoscenza esperta rimangono concetti fondamentali nell’IA, spesso integrati con approcci basati sull’apprendimento automatico per creare sistemi ibridi che combinano i vantaggi di entrambi i paradigmi.

Conclusione:

L’Intelligenza Artificiale è un campo multidisciplinare che affronta sfide concettuali profonde e problemi computazionali complessi. La comprensione dei limiti della computazione, la capacità di navigare spazi di ricerca esponenziali e la scelta di approcci di rappresentazione della conoscenza adeguati sono elementi chiave per lo sviluppo di sistemi intelligenti efficaci. I dibattiti filosofici sull’essenza dell’intelligenza e sulle implicazioni etiche e sociali dell’IA continuano a plasmare la direzione della ricerca e a sottolineare la necessità di un approccio responsabile e consapevole a questa potente tecnologia.


INDICE